chiark / gitweb /
svc/conntrack.in: Maintain config groups in a dictionary.
[tripe] / server / admin.c
index 58230baf80cf3183f5125db2eb3f495e88616eb0..8a3e62ca77f26d4b82fab6b7e2e5d2864694fb99 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;