how is rebound going to handle a change in resolv.conf? thats still a problem here
On Wednesday, 14 September 2016, Ted Unangst <t...@tedunangst.com> wrote: > So the plan is for rebound to be the 'system' resolver, with libc talking > to > rbeound and rebound talking to the cloud. The main wrinkle is how does > rebound > find the cloud? rebound.conf, but dhclient doesn't know anything about > rebound.conf, preferring to edit resolv.conf. But if rebound reads > resolv.conf, what does libc read? This has been a bit of a tangle until > now, > especially in scenarios like upgrades where rebound may not even be > running. > > And so I present the following diff to enable a smooth transition. It's > 'quantum' because it works whether or not rebound is running. No need to > open > the box. > > 1. rebound reads resolv.conf. This remains the config file for upstream > DNS. > > 2. libc now prepends its nameserver list with localhost, thus always > searching > for rebound. If it's not running, we just continue down the list. > > This covers the basic use case, where enabling rebound now requires no > additional work. No need to edit dhclient.conf, etc. It also works on > ramdisks. It also works with a mix of old and new binaries. Once you flip > resolv.conf back to upstream, old binaries will bypass rebound, but that's > ok. > The new rebound checks to make sure it's not stuck in a time loop, which is > never good. > > I also note this improves the situation for people who have been using > unbound > as a local cache, too. Just enable unbound and libc will use it > automatically. > > Particular edge case: if resolv.conf has no nameservers, then the localhost > default is not prepended. So libc won't try talking to rebound if it's > specifically configured not to (chroot). > > > Index: lib/libc/asr/asr.c > =================================================================== > RCS file: /cvs/src/lib/libc/asr/asr.c,v > retrieving revision 1.54 > diff -u -p -r1.54 asr.c > --- lib/libc/asr/asr.c 18 Jun 2016 15:25:28 -0000 1.54 > +++ lib/libc/asr/asr.c 15 Sep 2016 00:42:30 -0000 > @@ -549,6 +549,15 @@ pass0(char **tok, int n, struct asr_ctx > return; > if (n != 2) > return; > + /* prepend localhost to list */ > + if (ac->ac_nscount == 0) { > + if (asr_parse_nameserver((struct sockaddr *)&ss, > "127.0.0.1")) > + return; > + if ((ac->ac_ns[ac->ac_nscount] = calloc(1, > ss.ss_len)) == NULL) > + return; > + memmove(ac->ac_ns[ac->ac_nscount], &ss, > ss.ss_len); > + ac->ac_nscount += 1; > + } > if (asr_parse_nameserver((struct sockaddr *)&ss, tok[1])) > return; > if ((ac->ac_ns[ac->ac_nscount] = calloc(1, ss.ss_len)) == > NULL) > Index: usr.sbin/rebound/rebound.8 > =================================================================== > RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v > retrieving revision 1.4 > diff -u -p -r1.4 rebound.8 > --- usr.sbin/rebound/rebound.8 4 Dec 2015 04:50:43 -0000 1.4 > +++ usr.sbin/rebound/rebound.8 15 Sep 2016 00:57:21 -0000 > @@ -33,9 +33,7 @@ The options are as follows: > .Bl -tag -width Ds > .It Fl c Ar config > Specify an alternative configuration file, instead of the default > -.Pa /etc/rebound.conf . > -At present, the config file consists of a single line containing the next > -hop DNS server. > +.Pa /etc/resolv.conf . > .Nm > will reload the configuration file when sent a SIGHUP signal. > .It Fl d > @@ -46,8 +44,8 @@ does not > into the background. > .El > .Sh FILES > -.Bl -tag -width "/etc/rebound.confXX" -compact > -.It Pa /etc/rebound.conf > +.Bl -tag -width "/etc/resolv.confXX" -compact > +.It Pa /etc/resolv.conf > Default > .Nm > configuration file. > Index: usr.sbin/rebound/rebound.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v > retrieving revision 1.70 > diff -u -p -r1.70 rebound.c > --- usr.sbin/rebound/rebound.c 1 Sep 2016 10:57:24 -0000 1.70 > +++ usr.sbin/rebound/rebound.c 15 Sep 2016 00:53:26 -0000 > @@ -37,6 +37,7 @@ > #include <errno.h> > #include <getopt.h> > #include <stdarg.h> > +#include <ctype.h> > > #define MINIMUM(a,b) (((a)<(b))?(a):(b)) > > @@ -457,28 +458,41 @@ fail: > static int > readconfig(FILE *conf, union sockun *remoteaddr) > { > + const char ns[] = "nameserver"; > char buf[1024]; > + char *p; > struct sockaddr_in *sin = &remoteaddr->i; > struct sockaddr_in6 *sin6 = &remoteaddr->i6; > > - if (fgets(buf, sizeof(buf), conf) == NULL) > - return -1; > - buf[strcspn(buf, "\n")] = '\0'; > + while (fgets(buf, sizeof(buf), conf) != NULL) { > + buf[strcspn(buf, "\n")] = '\0'; > > - memset(remoteaddr, 0, sizeof(*remoteaddr)); > - if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) { > - sin->sin_len = sizeof(*sin); > - sin->sin_family = AF_INET; > - sin->sin_port = htons(53); > - return AF_INET; > - } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) { > - sin6->sin6_len = sizeof(*sin6); > - sin6->sin6_family = AF_INET6; > - sin6->sin6_port = htons(53); > - return AF_INET6; > - } else { > - return -1; > + if (strncmp(buf, ns, strlen(ns)) != 0) > + continue; > + p = buf + strlen(ns) + 1; > + while (isspace((unsigned char)*p)) > + p++; > + > + /* this will not end well */ > + if (strcmp(p, "127.0.0.1") == 0) > + continue; > + > + memset(remoteaddr, 0, sizeof(*remoteaddr)); > + if (inet_pton(AF_INET, p, &sin->sin_addr) == 1) { > + sin->sin_len = sizeof(*sin); > + sin->sin_family = AF_INET; > + sin->sin_port = htons(53); > + return AF_INET; > + } else if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == 1) { > + sin6->sin6_len = sizeof(*sin6); > + sin6->sin6_family = AF_INET6; > + sin6->sin6_port = htons(53); > + return AF_INET6; > + } else { > + return -1; > + } > } > + return -1; > } > > static int > @@ -665,7 +679,7 @@ main(int argc, char **argv) > struct kevent kev; > struct rlimit rlim; > struct timespec ts, *timeout = NULL; > - const char *confname = "/etc/rebound.conf"; > + const char *confname = "/etc/resolv.conf"; > FILE *conf; > > while ((ch = getopt(argc, argv, "c:d")) != -1) { > >