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) {
>
>

Reply via email to