Skip to content

wikimedia/operations-software-nss-dnsdc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reference implementation at resolv/nss_dns/dns-host.c and resolv/res_send.c

All various gethostbynames take the following:

- name
- buffer
- buflen
- errnop
- h_errnop
- af

And might return:
- ttl

Maybe write a wrapper?

4_r just uses this to return results:

struct gaih_addrtuple
  {
    struct gaih_addrtuple *next;
    char *name;
    int family;
    uint32_t addr[4];
    uint32_t scopeid;
  };

Installation
============

    make libnss_dnsdc.so.2
    install -m 0644 libnss_dnsdc.so.2 /lib
    /sbin/ldconfig -n /lib /usr/lib

Description
===========

- given: nameserver 1.2.3.4:53,0.1; nameserver 1.2.3.5:53,0.2; 1.2.3.6:53,0.5; attempts 3
  send query packet to 1.2.3.4:53, block waiting on timeout-or-response for
  0.1s. if timeout reached, send query to 1.2.3.5:53, block waiting on
  timeout-or-response for 0.2s. Repeat the process max other two times
  (attempts=3), at which point we actually fail.

- it's valid/expected/reasonable to configure a per-nameserver timeout of 0.0.
  This means don't even try to block/receive before moving on to the next
  (that's how you configure parallel queries to more than one NS at the "same
  time" it will spam through a list of ,0.0 nameservers before blocking and
  waiting for any one to respond)

- Use c-ares for low-level things like constructing requests and parsing
  responses

- do recv() calls with fixed timeout values set via SO_RCVTIMEO

- all the sends and all the receive-wait need using the same socket, and the
  same port number on the client side. ignore the source address of the
  response packet, just check QID

- separate config /etc/resolv-dcdns.conf; if the config file isn't present it
  just fails all requests as UNAVAIL (move on to next NSS module in the lookup
  list)

- ndots: fix at 1. If any dots, assume fully-qualified and don't append a
  domainname

- option "domain" eliminated in favor of "search"

- attempts N; search X Y Z; nameserver n.n.n.n:P,T
  P is port number, T is timeout in floating seconds

1) the nameserver IPs can be IPv4 or IPv6.  So we might need two sockets in the
   case both are configured, which may make simple timeouts waiting on all
   previous sends harder.  Maybe can get around this by either (a) limiting our
   module to v4 NS IPs only (kinda ugly in theory, but totally ok in practice I
   think) or (b) Using a v6 socket that maps v4 as well (there's a setsockopt for
   that)
   the v4-only thing is probably simpler for our first pass at this, we can
   always upgrade that part of the strategy later if we have to
2) The whole A+AAAA querying thing.  glibc's current default behavior is to
   fire 2x requests immediately to a nameserver when it polls it: one for A and
   one for AAAA.  And then they have an option to disable that and do them
   serially with timeouts because it confused some shitty home router/nat boxes.

   glibc's parallel approach seems reasonable: that leaves us with 2x
   outstanding answers to collect up, and making some policy decisions about when
   we terminate the search and return results to the user, if we get a response
   for one type and timeouts for the other...

   looking at how glibc's default nss-dns works for A+AAAA responses behaving
   differently might be informative as to current thinking.  Could also just
   reveal that what they're doing is awful