Viktor Dukhovni wrote in
 <Y4o4jwZfEOX/s...@straasha.imrryr.org>:
 |On Fri, Dec 02, 2022 at 06:03:51PM +0100, Steffen Nurpmeso wrote:
 |
 |> Simply add a dnsmasq local cache.  dnsmasq is a package on
 |> AlpineLinux, i use it.  (Including dnssec, and it even serves its
 |> cache back into a VPN, so that effectively only one instance does
 |> all the web queries.)  (I use it for over twenty years, i did DNS
 |> myself around this time.)
 |
 |Deploying dnsmasq does not do anything to address the limitations of the
 |stub resolver, at least not unless the C-library stub resolver has
 |special hooks to talk directly to dnsmasq over some dbus protocol or
 |similar, bypassing UDP and the 512-byte DNS message limit in the absense
 |of EDNS0.  I would naïvely expect MUSL libc to not have such hooks.
 |
 |Having neither EDNS0 with a reasonably generous buffer size (1400 and
 |1232 are common choices), nor TCP fallback on truncation is rather
 |unfortunate.  TCP support is NOT optional in DNS.

Yeah, that was standard over twenty years ago.
Actually musl resolver supports it:

  git show master:src/network/res_send.c
  int __res_send(const unsigned char *msg, int msglen, unsigned char *answer, 
int anslen)
  {
          int r;
          if (anslen < 512) {
                  unsigned char buf[512];
                  r = __res_send(msg, msglen, buf, sizeof buf);
                  if (r >= 0) memcpy(answer, buf, r < anslen ? r : anslen);
                  return r;
          }
          r = __res_msend(1, &msg, &msglen, &answer, &anslen, anslen);
          return r<0 || !anslen ? -1 : anslen;
  }

where msend goes

  int __res_msend(int nqueries, const unsigned char *const *queries,
          const int *qlens, unsigned char *const *answers, int *alens, int 
asize)
  {
          struct resolvconf conf;
          if (__get_resolv_conf(&conf, 0, 0) < 0) return -1;
          return __res_msend_rc(nqueries, queries, qlens, answers, alens, 
asize, &conf);
  }

and that finally goes

                        /* If answer is truncated (TC bit), fallback to TCP */
                        if ((answers[i][2] & 2) || (mh.msg_flags & MSG_TRUNC)) {
                                alens[i] = -1;
                                pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 
0);
                                r = start_tcp(pfd+i, family, ns+j, sl, 
queries[i], qlens[i]);
                                pthread_setcancelstate(cs, 0);
                                if (r >= 0) {
                                        qpos[i] = r;
                                        apos[i] = 0;
                                }
                                continue;

Using dnsmasq is a good thing.  (Though a fully caching stub
resolver and nothing else is too, of course.)

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)

Reply via email to