libsres(3)

πŸ“¦ version 2.2.3, in arch rolling, fedora 43, fedora 44

πŸ’– libsres β€” bestie's guide to sending queries & catching responses πŸ’–

okay so this is libsres(3), from the Programmer's Manual section (section 3, the "we write C and we're cute about it" section πŸ’…). it's the DNS resolver library bestie, and yes she comes with a whole personality. let's go 🌸


✨ NAME ✨

query_send(), response_rcv(), get() β€” send queries to a DNS name server and receive responses back. it's giving "ask the internet a question and hope she answers" πŸ¦‹

clone_ns(), clone_ns_list(), free_name_server(), free_name_servers() β€” manage name server lists. clone her, copy her, free her, clean up the whole friend group πŸ’…

print_response() β€” display the answers that came back from the name server. the reveal moment πŸ”₯


✨ SYNOPSIS ✨

#include <resolver.h>

int query_send(const char    *name,
          const unsigned short type,
          const unsigned short class,
          struct name_server  *nslist,
          int                 edns0_size,
          int                 *trans_id);

int response_recv(int         *trans_id,
          fd_set              *pending_desc,
          struct timeval      *closest_event,
          struct name_server  **respondent,
          unsigned char       **response,
          size_t              *response_length);

int get(const char          *name_n,
        const unsigned short type_h,
        const unsigned short class_h,
        struct name_server  *nslist,
        struct name_server  **respondent,
        unsigned char       **response,
        size_t              *response_length);

int clone_ns(struct name_server **cloned_ns,
        struct name_server *ns);

int clone_ns_list(struct name_server **ns_list,
                  struct name_server *orig_ns_list);

void free_name_server(struct name_server **ns);

void free_name_servers(struct name_server **ns);

void print_response(unsigned char *response,
          size_t response_length);

✨ DESCRIPTION ✨

okay so like, query_send() sends a query off to the name servers you listed in nslist. the query itself is the <name, class, type> tuple (iconic trio, no notes ✨), and trans_id gives you a handle to this whole transaction inside the libsres library. and the buffer size that gets advertised in the EDNS0 option? you set that with the ends0_size argument. slay.

response_recv() returns the answers, if there are any, from the name server that actually responded for the query identified by trans_id. the response shows up in response, and the name server who answered comes back in respondent. the length of the response, in bytes, lands in response_length. she tells you everything 🫢

get() is the wrapper bestie around query_send() and response_recv(). it sends the request, then blocks until some name server responds or until the request times out. and hear me on this one: the libsres library does not automatically follow referrals β€” responses containing referrals are treated as valid responses. periodt.

the memory that *respondent points to is internally allocated by the libsres library, so you have to free it with free_name_server(). you can free a whole list of name servers with free_name_servers(). wanna make a copy of a name server? that's clone_ns(). copy of a whole name server list? that's clone_ns_list(). match made in heaven πŸ’–

print_response() is the convenient way to display the answers returned in response by the name server. the unboxing ✨


πŸŽ€ the name_server structure πŸŽ€

she's defined in resolver.h like this, and she's exactly this, don't touch:

#define NS_MAXCDNAME    255
struct name_server
{
    unsigned char ns_name_n[NS_MAXCDNAME];
    void *ns_tsig;
    unsigned int ns_security_options;
    unsigned int ns_status;
    unsigned long ns_options;
    int ns_retry;
    int ns_retrans;
    struct name_server *ns_next;
    int ns_number_of_addresses;
    struct sockaddr_storage **ns_address;
};
  • ns_name_n β€” the name of the zone this name server is authoritative for. her whole domain, literally.
  • ns_tsig β€” the tsig key that should be used to protect messages sent to this name server. ⚠️ this field is currently unused and must be set to NULL. don't come for her, she's not active yet.
  • ns_security_options β€” the security options for the zone. ⚠️ this field is currently unused and must be set to ZONE_USE_NOTHING. respect the assignment bestie.
  • ns_status β€” the status of the zone, i.e. how the zone info was obtained. the invoker must set this value to SR_ZI_STATUS_UNSET. zone info obtained through referrals has a value of SR_ZI_STATUS_LEARNED for this field. glow-up arc πŸ“ˆ
  • ns_options β€” specifies additional resolver flags. the currently defined flags are:
    • SR_QUERY_RECURSE, which sets the "Recursion Desired" flag
    • SR_QUERY_SET_DO, which sets the "DNSSEC OK" bit in the EDNS0 header
    • SR_QUERY_SET_CD, which sets the "DNSSEC CD" bit in the EDNS0 header
    • SR_QUERY_DEBUG, which enables debugging
    • and SR_QUERY_VALIDATING_STUB_FLAGS sets both SR_QUERY_SET_DO and SR_QUERY_SET_CD. two for one, we love a bundle πŸ’…
  • ns_retry β€” the maximum number of attempts that must be made to get a name from an unresponsive name server before giving up. know your limits βœ‹
  • ns_retrans β€” the retransmission interval, in seconds, for queries sent to unresponsive name servers. give her a sec πŸ•
  • ns_next β€” the address of the next name server in the list. the group chat chain πŸ”—
  • ns_number_of_addresses β€” the number of elements in the array ns_addresses. ⚠️ this field is currently unused. (yes the heading says ns_addresses, we report what the page says, no cap)
  • ns_addresses β€” the IP address of the name server. where she lives πŸ“

✨ OTHER SYMBOLS EXPORTED ✨

the libsres library also exports these BIND functions, and you can find their documentation in the BIND sources and documentation manuals (go read those, i'm not doing their whole job for them 😌):

res_nametoclass
res_nametotype
ns_name_ntop
ns_name_pton
ns_name_unpack
ns_parse_ttl
p_class
p_section
p_type

and here's the tea: the p_type() function exported from libsres has been augmented so it recognizes the various DNSSEC type codes such as DNSKEY, RRSIG, NSEC, NSEC3 and DLV. she got upgraded and she ate πŸ”₯


✨ RETURN VALUES ✨

every one of these, no skipping, we are thorough in this household πŸ’œ

  • SR_UNSET β€” No error.
  • SR_CALL_ERROR β€” An invalid parameter was passed to get(), query_send(), or response_recv().
  • SR_INTERNAL_ERROR β€” The resolver encountered some internal error.
  • SR_TSIG_ERROR β€” The resolver encountered some TSIG-related error. this is currently not implemented.
  • SR_NO_ANSWER β€” No answers were received from any name server.
  • SR_NO_ANSWER_YET β€” No answer currently available; the query is still active. she's still cooking 🍳
  • SR_HEADER_ERROR β€” The length and count of records in the header were incorrect.
  • SR_NXDOMAIN β€” The queried name did not exist. she's not real bestie 😭
  • SR_FORMERR β€” The name server was not able to parse the query message.
  • SR_SERVFAIL β€” The name server was not reachable.
  • SR_NOTIMPL β€” A particular functionality is not yet implemented.
  • SR_REFUSED β€” The name server refused to answer this query. rude.
  • SR_DNS_GENERIC_FAILURE β€” Other failure returned by the name server and reflected in the returned message RCODE.
  • SR_EDNS_VERSION_ERROR β€” The EDNS version was not recognized
  • SR_NAME_EXPANSION_FAILURE β€” A failure was encountered while trying to expand a compressed domain name.

✨ CURRENT STATUS ✨

  • There is currently no support for IPv6. yeah. i know. 😭
  • There is limited support for specifying resolver policy; members of the struct name_server are still subject to change. so don't get too attached to her fields, they might glow up again πŸ’…

Copyright 2004-2013 SPARTA, Inc. All rights reserved. See the COPYING file included with the dnssec-tools package for details.


✨ SEE ALSO ✨


okay that's the whole page bestie, you're officially educated πŸŽ“πŸ’– this was libsres(3) from the Programmer's Manual, and the page footer said it was generated by perl v5.14.3 on 2013-02-27 β€” so shoutout to that vintage energy, she's been iconic since 2013 and she's still serving πŸ«Άβœ¨πŸ’…

πŸ“¦ where this page comes from