chiark / gitweb /
server/admin.c (a_resolve): Parse using the `aftab' table.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 16 Sep 2017 18:09:40 +0000 (19:09 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 28 Jun 2018 23:26:40 +0000 (00:26 +0100)
Also, introduce a new `ANY' pseudo-family which does the right thing
using the resolver.

server/admin.c
server/tripe-admin.5.in

index 0ec187ce5e581bd21df335b8063f756313c393f1..72f42f297581e1e7b55bc21f6cd970ed230b2751 100644 (file)
@@ -1100,17 +1100,29 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
 {
   struct timeval tv;
   unsigned long pt;
 {
   struct timeval tv;
   unsigned long pt;
+  int af = AF_UNSPEC;
+  const char *fam = "ANY";
   char *p;
   char *p;
-  int i = 0;
+  int i = 0, j;
 
   /* --- Fill in the easy bits of address --- */
 
   r->bg.tag = "<starting>";
   r->addr = 0;
   r->func = func;
 
   /* --- Fill in the easy bits of address --- */
 
   r->bg.tag = "<starting>";
   r->addr = 0;
   r->func = func;
-  if (mystrieq(av[i], "inet")) i++;
+  if (mystrieq(av[i], "any"))
+    { 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);
+      fam = aftab[j].name;
+      af = aftab[j].af;
+      i++;
+      break;
+    }
+  }
   if (ac - i != 1 && ac - i != 2) {
   if (ac - i != 1 && ac - i != 2) {
-    a_fail(a, "bad-addr-syntax", "[inet] ADDRESS [PORT]", A_END);
+    a_fail(a, "bad-addr-syntax", "[FAMILY] ADDRESS [PORT]", A_END);
     goto fail;
   }
   r->addr = xstrdup(av[i]);
     goto fail;
   }
   r->addr = xstrdup(av[i]);
@@ -1141,8 +1153,18 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
 
   if (a_bgadd(a, &r->bg, tag, a_rescancel))
     goto fail;
 
   if (a_bgadd(a, &r->bg, tag, a_rescancel))
     goto fail;
-  T( trace(T_ADMIN, "admin: %u, resop %s, hostname `%s'",
-          a->seq, BGTAG(r), r->addr); )
+  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 --- */
 
 
   /* --- If the name is numeric, do it the easy way --- */
 
@@ -1168,6 +1190,12 @@ fail:
   func(r, ARES_FAIL);
   if (r->addr) xfree(r->addr);
   xfree(r);
   func(r, ARES_FAIL);
   if (r->addr) xfree(r->addr);
   xfree(r);
+  return;
+
+fail_release:
+  func(r, ARES_FAIL);
+  xfree(r->addr);
+  a_bgrelease(&r->bg);
 }
 
 /*----- Option parsing ----------------------------------------------------*/
 }
 
 /*----- Option parsing ----------------------------------------------------*/
index 43f772546d3ab832f19e5f969de7e232eca93218..44af6a5828870a7691268cf8d84d6787ab7a58fd 100644 (file)
@@ -251,21 +251,40 @@ the meanings of the subsequent tokens depend on the address family.
 Address family tokens are not case-sensitive on input; on output, they
 are always in upper-case.
 .PP
 Address family tokens are not case-sensitive on input; on output, they
 are always in upper-case.
 .PP
-At present, only one address family is understood.
+The following address families are recognized.
+.TP
+.BI "ANY " address " \fR[" port \fR]
+An address and port number for any supported address family.  On output,
+.B tripe
+never uses this form.  On input, the
+.I address
+is examined: if it is a numeric address for some recognized address
+family, then it is interpreted as such; otherwise it is looked up using
+the DNS (in the background).  The background resolver's address-sorting
+rules apply, and
+.B tripe
+simply takes the first address in the returned list which is of a
+supported address family.  Symbolic port numbers are permitted; if
+omitted, the default port 4070 is used.
 .TP
 .BI "INET " address " \fR[" port \fR]
 An Internet socket, naming an IPv4 address and UDP port.  On output, the
 .TP
 .BI "INET " address " \fR[" port \fR]
 An Internet socket, naming an IPv4 address and UDP port.  On output, the
-address is always in numeric dotted-quad form, and the port is given as
-a plain number.  On input, DNS hostnames and symbolic port names are
-permitted; if omitted, the default port 4070 is used.  Name resolution
-does not block the main server, but will block the requesting client,
-unless the command is run in the background.
+.I address
+is always in numeric dotted-quad form, and the
+.I port
+is given as a plain decimal number.  On input, DNS hostnames and
+symbolic port names are permitted; if omitted, the default port 4070 is
+used.
 .PP
 If, on input, no recognized address family token is found, the following
 tokens are assumed to represent an
 .PP
 If, on input, no recognized address family token is found, the following
 tokens are assumed to represent an
-.B INET
+.B ANY
 address.  Addresses output by the server always have an address family
 address.  Addresses output by the server always have an address family
-token.
+token, and do not use
+.BR ANY .
+.PP
+Name resolution never blocks the main server, but will block the
+requesting client, unless the command is run in the background.
 .SS "Key-value output"
 Some commands (e.g.,
 .B STATS
 .SS "Key-value output"
 Some commands (e.g.,
 .B STATS