server/: Eliminate the remaining address-family-specific knowledge.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 29 Sep 2017 08:58:08 +0000 (09:58 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 28 Jun 2018 23:29:23 +0000 (00:29 +0100)
Outside of a few functions in `addrmap.c' and `servutil.c'.  Name
resolution now fails softly if it encounters an unexpected address
family (which can happen because of numeric conversion through
`getaddrinfo'), and the ADNS query flags are now set via the `aftab'.

server/admin.c
server/servutil.c
server/tripe.h

index 58230ba..8a3e62c 100644 (file)
@@ -1233,7 +1233,10 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
     { fam = "ANY"; af = AF_UNSPEC; i++; }
   else for (j = 0; j < NADDRFAM; j++) {
     if (mystrieq(av[i], aftab[j].name)) {
-      assert(udpsock[j].fd >= 0);
+      if (udpsock[j].fd < 0) {
+       a_fail(a, "disabled-address-family", "%s", aftab[j].name, A_END);
+       goto fail;
+      }
       fam = aftab[j].name;
       af = aftab[j].af;
       i++;
@@ -1275,19 +1278,9 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
   T( trace(T_ADMIN, "admin: %u, resop %s, hostname `%s', family `%s'",
           a->seq, BGTAG(r), r->addr, fam); )
 
-  /* --- Make sure the address family is something we can implement --- */
-
-  if (af != AF_UNSPEC && af != AF_INET) {
-    T( trace(T_ADMIN, "admin: resop %s failed: unsupported address family",
-            BGTAG(r)); )
-    a_bgfail(&r->bg, "resolve-error", "%s", r->addr, A_END);
-    goto fail_release;
-  }
-  assert(udpsock[AFIX_INET].fd >= 0);
-
   /* --- If the name is numeric, do it the easy way --- */
 
-  aihint.ai_family = AF_INET;
+  aihint.ai_family = af;
   aihint.ai_socktype = SOCK_DGRAM;
   aihint.ai_protocol = IPPROTO_UDP;
   aihint.ai_flags = AI_NUMERICHOST;
@@ -1320,7 +1313,11 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
   tv.tv_sec += T_RESOLVE;
   sel_addtimer(&sel, &r->t, &tv, a_restimer, r);
 #ifdef HAVE_LIBADNS
-  qf = adns_qf_search | adns_qf_want_ipv4;
+  qf = adns_qf_search;
+  for (j = 0; j < NADDRFAM; j++) {
+    if ((af == AF_UNSPEC || af == aftab[i].af) && udpsock[j].fd >= 0)
+      qf |= aftab[j].qf;
+  }
   if ((err = adns_submit(ads, r->addr, adns_r_addr, qf, r, &r->q)) != 0) {
     T( trace(T_ADMIN, "admin: resop %s adns_submit failed: %s",
             BGTAG(r), strerror(err)); )
@@ -1328,6 +1325,16 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
     goto fail_release;
   }
 #else
+  if (af != AF_UNSPEC && af != AF_INET) {
+    T( trace(T_ADMIN, "admin: resop %s failed: unsupported address family",
+            BGTAG(r)); )
+    a_bgfail(&r->bg, "resolve-error", "%s", r->addr, A_END);
+    goto fail_release;
+  }
+  if (udpsock[AFIX_INET].fd < 0) {
+    a_bgfail(&r->bg, "disabled-address-family", "INET", A_END);
+    goto fail_release;
+  }
   bres_byname(&r->r, r->addr, a_resolved, r);
 #endif
   return;
index b6fbf5b..a4de378 100644 (file)
@@ -124,7 +124,11 @@ int mystrieq(const char *x, const char *y)
 /*----- Address handling --------------------------------------------------*/
 
 const struct addrfam aftab[] = {
-#define DEF(af) { AF_##af, #af },
+#ifdef HAVE_LIBADNS
+#  define DEF(af, qf) { AF_##af, #af, adns_qf_##qf },
+#else
+#  define DEF(af, qf) { AF_##af, #af },
+#endif
   ADDRFAM(DEF)
 #undef DEF
 };
index 6946c5f..f447be5 100644 (file)
@@ -420,10 +420,10 @@ extern const bulkops bulktab[];
 /* --- The address-family table --- */
 
 #define ADDRFAM(_)                                                     \
-  _(INET)
+  _(INET,      want_ipv4)
 
 enum {
-#define ENUM(af) AFIX_##af,
+#define ENUM(af, qf) AFIX_##af,
   ADDRFAM(ENUM)
 #undef ENUM
   NADDRFAM
@@ -432,6 +432,9 @@ enum {
 extern const struct addrfam {
   int af;
   const char *name;
+#ifdef HAVE_LIBADNS
+  adns_queryflags qf;
+#endif
 } aftab[NADDRFAM];
 
 /* --- Socket addresses --- *