chiark / gitweb /
src/setup.c: Check netmask more carefully.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 3 May 2014 14:35:29 +0000 (15:35 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 3 May 2014 14:35:50 +0000 (15:35 +0100)
[crybaby ~/src/adns/build]RES_CONF_TEXT="sortlist 172.29.199.1/24" RES_OPTIONS="adns_checkc:entex" adnshost -ta www-cache.distorted.org.uk
adnshost: ../src/check.c:83: checkc_global: Assertion `!(ads->sortlist[i].base.s_addr & ~ads->sortlist[i].mask.s_addr)' failed.
Aborted

Unfortunately, `ccf_sortlist' only checked that the free bits of the
network address are clear when given a general netmask, so if you give a
prefix length or leave it implicit then you hit a consistency check
failure later.

Check the mask later on, after all of the variants are handled.  There's
a little bit of variation in the message.

Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
src/setup.c

index 44c3cee0ad1e9652563b2548046dd03b3d439b25..e6f1e55d85993f264bdfacf5c9711e87ad4e0dbd 100644 (file)
@@ -152,6 +152,7 @@ static void ccf_sortlist(adns_state ads, const char *fn,
                         int lno, const char *buf) {
   const char *word;
   char tbuf[200], *slash, *ep;
+  const char *maskwhat;
   struct in_addr base, mask;
   int l;
   unsigned long initial, baselocal;
@@ -182,16 +183,13 @@ static void ccf_sortlist(adns_state ads, const char *fn,
 
     if (slash) {
       if (strchr(slash,'.')) {
+       maskwhat = "mask";
        if (!inet_aton(slash,&mask)) {
          configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash);
          continue;
        }
-       if (base.s_addr & ~mask.s_addr) {
-         configparseerr(ads,fn,lno, "mask `%s' in sortlist"
-                        " overlaps address `%s'",slash,tbuf);
-         continue;
-       }
       } else {
+       maskwhat = "prefix length";
        initial= strtoul(slash,&ep,10);
        if (*ep || initial>32) {
          configparseerr(ads,fn,lno,"mask length `%s' invalid",slash);
@@ -200,6 +198,7 @@ static void ccf_sortlist(adns_state ads, const char *fn,
        mask.s_addr= htonl((0x0ffffffffUL) << (32-initial));
       }
     } else {
+      maskwhat = "implied mask";
       baselocal= ntohl(base.s_addr);
       if (!baselocal & 0x080000000UL) /* class A */
        mask.s_addr= htonl(0x0ff000000UL);
@@ -215,6 +214,13 @@ static void ccf_sortlist(adns_state ads, const char *fn,
       }
     }
 
+    if (base.s_addr & ~mask.s_addr) {
+      configparseerr(ads,fn,lno, "%s `%s' in sortlist"
+                    " overlaps address `%s'",maskwhat,
+                    slash ? slash : inet_ntoa(mask), tbuf);
+      continue;
+    }
+
     ads->sortlist[ads->nsortlist].base= base;
     ads->sortlist[ads->nsortlist].mask= mask;
     ads->nsortlist++;