ARES_SEARCH(3)

πŸ“¦
version 1.34.9 Β· 2 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, centos-stream 10, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0, ubuntu stonking

πŸ’– ARES_SEARCH(3) β€” Library Functions Manual πŸ’–

okay bestie, pull up a chair, because we're about to talk about ares_search from the c-ares library and honestly? it's giving ✨DNS resolver royalty✨. no cap.


🌸 NAME 🌸

ares_search β€” Initiate a DNS query with domain search. yep that's the whole vibe. πŸ”


✨ SYNOPSIS ✨

#include <ares.h>

typedef void (*ares_callback_dnsrec)(void *arg,
                                     ares_status_t status,
                                     size_t timeouts,
                                     const ares_dns_record_t *dnsrec);

void ares_search_dnsrec(ares_channel_t *channel,
                        const ares_dns_record_t *dnsrec,
                        ares_callback_dnsrec callback, void *arg);

typedef void (*ares_callback)(void *arg, int status,
                              int timeouts, unsigned char *abuf,
                              int alen);

void ares_search(ares_channel_t *channel, const char *name,
                 int dnsclass, int type,
                 ares_callback callback, void *arg);

look at those function signatures, so clean, so iconic πŸ’… copy them exactly if you're writing code, i am literally begging you.


πŸ¦‹ DESCRIPTION πŸ¦‹

so. ares_search kicks off a whole series of single-question DNS queries on the name service channel you pass in as channel. it uses the channel's search domains, plus a host alias file that gets named by the HOSTALIAS environment variable. multitasking queen honestly πŸ‘‘

the name parameter is either the alias name or the base of the query name, and it's a NUL-terminated C string of period-separated labels. big deal alert: if name ends with a period, the channel's search domains will not be used. periodt. πŸ”₯

and listen β€” periods and backslashes inside a label have to be escaped with a backslash. don't skip that, it will absolutely ruin your day 😭

dnsclass and type give the class and type of the query, using the values defined in <arpa/nameser.h>.

when the query sequence is complete or has failed, the ares library invokes callback. and the timing? could be immediately, or it could happen later during a call to ares_process(3) or ares_destroy(3). so don't assume, bestie. πŸ™ˆ

⚠️ threading tea: if you're calling this from a thread other than the one the main program event loop is running on, you need to be careful to make sure any file descriptor lists are updated immediately within the eventloop. and when the associated callback gets called, it's called with a channel lock, so keep any processing minimal β€” otherwise you risk DNS channel stalls. no blocking in the callback, i'm serious 🫢

πŸ“¬ the callback arguments πŸ“¬

the callback argument arg is copied straight from the ares_search argument arg β€” same energy, same value. ✨

the callback argument status tells you whether the query sequence ended with a successful query, and if it didn't, how it failed. it can be any of these:

  • ARES_SUCCESS β€” a query completed successfully. slay! πŸŽ‰
  • ARES_ENODATA β€” no query completed successfully; when the query was tried without a search domain appended, a response came back with no answers. empty. void. the audacity πŸ’€
  • ARES_EFORMERR β€” a query completed but the server claimed the query was malformatted. rude, but okay. 😭
  • ARES_ESERVFAIL β€” no query completed successfully; when the query was tried without a search domain appended, the server claimed to have experienced a failure. (this code can only occur if the ARES_FLAG_NOCHECKRESP flag was specified at channel initialization time; otherwise, such responses are ignored at the ares_send(3) level.) πŸ™ˆ
  • ARES_ENOTFOUND β€” no query completed successfully; when the query was tried without a search domain appended, the server reported that the queried-for domain name was not found. it's not there. it never was. πŸ’€
  • ARES_ENOTIMP β€” a query completed but the server does not implement the operation requested by the query. (this code can only occur if the ARES_FLAG_NOCHECKRESP flag was specified at channel initialization time; otherwise, such responses are ignored at the ares_send(3) level.) 🚫
  • ARES_EREFUSED β€” a query completed but the server refused the query. (this code can only occur returned if the ARES_FLAG_NOCHECKRESP flag was specified at channel initialization time; otherwise, such responses are ignored at the ares_send(3) level.) the server said "not today" πŸ™…
  • ARES_TIMEOUT β€” no name servers responded to a query within the timeout period. they ghosted you. πŸ‘»
  • ARES_ECONNREFUSED β€” no name servers could be contacted. couldn't even reach them fr fr πŸ“΅
  • ARES_ENOMEM β€” memory was exhausted. she's tired, she needs a nap 😴
  • ARES_ECANCELLED β€” the query was cancelled. called it off, no hard feelings πŸŽ€
  • ARES_EDESTRUCTION β€” the name service channel channel is being destroyed; the query will not be completed. rip πŸͺ¦
  • ARES_ENOSERVER β€” no query completed successfully; no DNS servers were configured on the channel. literally nobody home 🏚️

the callback argument timeouts reports how many times a query timed out during the execution of the given request. count those L's πŸ“Š

πŸ“¦ about abuf and alen πŸ“¦

if a query completed successfully, the callback argument abuf points to a result buffer of length alen. if the query did not complete successfully, abuf will usually be NULL and alen will usually be 0 β€” but heads up, in some cases an unsuccessful query result may still be placed in abuf. surprises happen 🎁

⚠️ the abuf buffer is owned by the c-ares library and is only valid for the duration of the callback. the callback must not modify or free it, and must not retain a reference to it after returning β€” treat it as read-only. this parameter is intentionally not declared const solely to preserve API/ABI compatibility with existing applications. so yeah, it looks mutable, but don't. πŸ”’

🌈 ares_search_dnsrec β€” the upgraded version 🌈

the ares_search_dnsrec(3) function behaves identically to ares_search(3), but instead of a name, class and type, it takes an initialized and filled DNS record object as its second argument, dnsrec, to use for queries. this object is used as the base for the queries, and it must itself represent a valid query for a single name. main character energy, but make it valid πŸ‘‘

important deets:

  • the search domains will only be appended to the name in the question section; RRs on the DNS record object will not be affected.
  • the callback argument is of type ares_callback_dnsrec. this callback behaves identically to ares_callback, but is invoked with a parsed DNS record object dnsrec rather than a raw buffer with length.
  • note that this object is read-only. don't touch. πŸ™…β™€οΈ

and ares_search_dnsrec(3) returns an ares_status_t response code. this may be useful to know that the query was enqueued properly. the response code does not reflect the result of the query β€” just the result of the enqueuing of the query. read that twice, bestie, it's a classic gotcha 😌


🌟 AVAILABILITY 🌟

ares_search_dnsrec(3) was introduced in c-ares 1.28.0. she's new here but she's thriving ✨


πŸ‘€ SEE ALSO πŸ‘€


and that's the whole page, babe 🫢 this one's from the Library Functions Manual, dated 24 July 1998 β€” a true vintage icon, older than most of us but still absolutely serving. stay resolved, stay searched, and remember: escape your backslashes. mwah πŸ’‹πŸ’–πŸŒΈ