chiark / gitweb /
Do address-family dispatch with lots of switchy functions.
[adns] / src / types.c
index 3bed29e94bfe8d67c5c27e599c70bcbcb324f9e4..18cf15939737f1dd49db2e72ff32cc3ab0409a14 100644 (file)
  * _mailbox                   (pap +pap_mailbox822)
  * _rp                        (pa)
  * _soa                       (pa,mf,cs)
- * _srv*                      (qdpl,(pap),pa,mf,di,(csp),cs,postsort)
+ * _srv*                      (ckl,(pap),pa,mf,di,(csp),cs,postsort)
  * _byteblock                 (mf)
  * _opaque                    (pa,cs)
  * _flat                      (mf)
  *
  * within each section:
- *    qdpl_*
+ *    ckl_*
  *    pap_*
  *    pa_*
  *    dip_*
@@ -275,10 +275,9 @@ static int search_sortlist(adns_state ads, int af, const void *ad) {
 
   for (i=0, slp=ads->sortlist;
        i<ads->nsortlist &&
-       !(af == slp->ai->af &&
-        slp->ai->matchp(ad, &slp->base, &slp->mask)) &&
-       !(v6mappedp && slp->ai->af == AF_INET &&
-        slp->ai->matchp(&a, &slp->base, &slp->mask));
+        !adns__addr_match_p(af,ad, slp->af,&slp->base,&slp->mask) &&
+        !(v6mappedp &&
+          adns__addr_match_p(AF_INET,&a, slp->af,&slp->base,&slp->mask));
        i++, slp++);
   return i;
 }
@@ -449,15 +448,7 @@ static adns_status pa_addr(const parseinfo *pai, int cbyte,
 
 static int search_sortlist_sa(adns_state ads, const struct sockaddr *sa)
 {
-  const afinfo *ai = 0;
-
-  switch (sa->sa_family) {
-    case AF_INET: ai = &adns__inet_afinfo; break;
-    case AF_INET6: ai = &adns__inet6_afinfo; break;
-  }
-  assert(ai);
-
-  return search_sortlist(ads, sa->sa_family, ai->sockaddr_to_inaddr(sa));
+  return search_sortlist(ads, sa->sa_family, adns__sockaddr_to_inaddr(sa));
 }
 
 static int dip_sockaddr(adns_state ads,
@@ -1149,7 +1140,7 @@ static void icb_ptr(adns_query parent, adns_query child) {
     return;
   }
 
-  queried= &parent->ctx.pinfo.ptr_parent_addr.addr;
+  queried= &parent->ctx.tinfo.ptr.addr.addr;
   for (i=0, found=cans->rrs.bytes; i<cans->nrrs; i++, found += cans->rrsz) {
     if (!memcmp(queried,found,cans->rrsz)) {
       if (!parent->children.head) {
@@ -1165,24 +1156,28 @@ static void icb_ptr(adns_query parent, adns_query child) {
   adns__query_fail(parent,adns_s_inconsistent);
 }
 
+static adns_status ckl_ptr(adns_state ads, adns_queryflags flags,
+                          union checklabel_state *css, qcontext *ctx,
+                          int labnum, const char *label, int lablen)
+{
+  if (lablen) {
+    if (adns__revparse_label(&css->ptr, labnum, label,lablen))
+      return adns_s_querydomainwrong;
+  } else {
+    if (adns__revparse_done(&css->ptr, labnum,
+                           &ctx->tinfo.ptr.rev_rrtype,
+                           &ctx->tinfo.ptr.addr))
+      return adns_s_querydomainwrong;
+  }
+  return adns_s_ok;
+}
+
 static adns_status pa_ptr(const parseinfo *pai, int dmstart,
                          int max, void *datap) {
-  static const struct {
-    const afinfo *ai;
-    const char *const tail[3];
-  } expectdomain[] = {
-    { &adns__inet_afinfo, { DNS_INADDR_ARPA, 0 } },
-    { &adns__inet6_afinfo, { DNS_IP6_ARPA, 0 } }
-  };
-  enum { n_ed = sizeof(expectdomain)/sizeof(expectdomain[0]) };
-  
   char **rrp= datap;
   adns_status st;
-  struct afinfo_addr *ap;
-  findlabel_state fls;
-  byte ipv[n_ed][32];
-  int cbyte, i, j, foundj = -1, lablen, labstart, id, f, ac;
-  const char *tp;
+  adns_rrtype rrtype = pai->qu->ctx.tinfo.ptr.rev_rrtype;
+  int cbyte, id;
   adns_query nqu;
   qcontext ctx;
 
@@ -1192,65 +1187,17 @@ static adns_status pa_ptr(const parseinfo *pai, int dmstart,
   if (st) return st;
   if (cbyte != max) return adns_s_invaliddata;
 
-  ap= &pai->qu->ctx.pinfo.ptr_parent_addr;
-  if (!ap->ai) {
-    adns__findlabel_start(&fls, pai->ads, -1, pai->qu,
-                         pai->qu->query_dgram, pai->qu->query_dglen,
-                         pai->qu->query_dglen, DNS_HDRSIZE, 0);
-
-    f = (1 << n_ed) - 1; /* superposition of address types */
-    for (i = 0;; i++) {
-      st= adns__findlabel_next(&fls,&lablen,&labstart); assert(!st);
-      if (lablen <= 0) break;
-      for (j = 0; j < n_ed; j++) {
-       if (!(f & (1 << j))) continue;
-       if (i < expectdomain[j].ai->nrevcomp) {
-         ac = expectdomain[j].ai->rev_parsecomp(
-           pai->qu->query_dgram + labstart, lablen);
-         if (ac < 0) goto mismatch;
-         assert(i < sizeof(ipv[j]));
-         ipv[j][i] = ac;
-       } else {
-         tp = expectdomain[j].tail[i - expectdomain[j].ai->nrevcomp];
-         if (!tp ||
-             strncmp(pai->qu->query_dgram + labstart, tp, lablen) != 0 ||
-             tp[lablen] != 0)
-           goto mismatch;
-       }
-       continue;
-
-      mismatch:
-       f &= ~(1 << j);
-       if (!f) return adns_s_querydomainwrong;
-      }
-    }
-
-    if (lablen < 0) return adns_s_querydomainwrong;
-    for (j = 0; j < n_ed; j++) {
-      if (!(f & (1 << j))) continue;
-      if (i >= expectdomain[j].ai->nrevcomp &&
-         !expectdomain[j].tail[i - expectdomain[j].ai->nrevcomp])
-       { foundj = j; continue; }
-      f &= ~(1 << j);
-      if (!f) return adns_s_querydomainwrong;
-    }
-    assert(foundj >= 0 && f == (1 << foundj)); /* collapsed to a single type */
-
-    ap->ai = expectdomain[foundj].ai;
-    ap->ai->rev_mkaddr(&ap->addr, ipv[foundj]);
-  }
-
   st= adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id,
                            pai->dgram, pai->dglen, dmstart,
-                           ap->ai->rrtype, adns_qf_quoteok_query);
+                           rrtype, adns_qf_quoteok_query);
   if (st) return st;
 
   ctx.ext= 0;
   ctx.callback= icb_ptr;
   memset(&ctx.pinfo,0,sizeof(ctx.pinfo));
   memset(&ctx.tinfo,0,sizeof(ctx.tinfo));
-  st= adns__internal_submit(pai->ads, &nqu, adns__findtype(ap->ai->rrtype),
-                           ap->ai->rrtype, &pai->qu->vb, id,
+  st= adns__internal_submit(pai->ads, &nqu, adns__findtype(rrtype),
+                           rrtype, &pai->qu->vb, id,
                            adns_qf_quoteok_query, pai->now, &ctx);
   if (st) return st;
 
@@ -1459,36 +1406,18 @@ static adns_status cs_soa(vbuf *vb, const void *datap) {
 }
 
 /*
- * _srv*  (pa*2,di,cs*2,qdpl,postsort)
+ * _srv*  (pa*2,di,cs*2,ckl,postsort)
  */
 
-static adns_status qdpl_srv(adns_state ads,
-                           const char **p_io, const char *pe, int labelnum,
-                           char label_r[DNS_MAXDOMAIN], int *ll_io,
-                           adns_queryflags flags,
-                           const typeinfo *typei) {
-  int useflags;
-  const char *p_orig;
-  adns_status st;
-
-  if (labelnum < 2 && !(flags & adns_qf_quoteok_query)) {
-    useflags= adns_qf_quoteok_query;
-    p_orig= *p_io;
-  } else {
-    useflags= flags;
-    p_orig= 0;
-  }
-  st= adns__qdpl_normal(ads, p_io,pe, labelnum,label_r, ll_io, useflags,typei);
-  if (st) return st;
-
-  if (p_orig) {
-    int ll= *ll_io;
-    if (!ll || label_r[0]!='_')
-      return adns_s_querydomaininvalid;
-    if (memchr(p_orig+1, '\\', pe - (p_orig+1)))
-      return adns_s_querydomaininvalid;
+static adns_status ckl_srv(adns_state ads, adns_queryflags flags,
+                          union checklabel_state *css, qcontext *ctx,
+                          int labnum, const char *label, int lablen)
+{
+  if (labnum < 2 && !(flags & adns_qf_quoteok_query)) {
+    if (!lablen || label[0] != '_') return adns_s_querydomaininvalid;
+    label++; lablen--;
   }
-  return adns_s_ok;
+  return adns__ckl_hostname(ads, flags, css, ctx, labnum, label, lablen);
 }
 
 static adns_status pap_srv_begin(const parseinfo *pai, int *cbyte_io, int max,
@@ -1704,14 +1633,14 @@ static void mf_flat(adns_query qu, void *data) { }
 
 #define DEEP_TYPE(code,rrt,fmt,memb,parser,comparer,printer)   \
 { adns_r_##code & adns_rrt_reprmask, rrt,fmt,TYPESZ_M(memb),   \
-    mf_##memb, printer,parser,comparer, adns__qdpl_normal,0,0,0 }
+    mf_##memb, printer,parser,comparer, adns__ckl_hostname,0,0,0 }
 #define FLAT_TYPE(code,rrt,fmt,memb,parser,comparer,printer)   \
 { adns_r_##code & adns_rrt_reprmask, rrt,fmt,TYPESZ_M(memb),   \
-    mf_flat, printer,parser,comparer, adns__qdpl_normal,0,0,0 }
+    mf_flat, printer,parser,comparer, adns__ckl_hostname,0,0,0 }
 #define XTRA_TYPE(code,rrt,fmt,memb,parser,comparer,printer,              \
-                 makefinal,qdpl,postsort,getrrsz,sender)                  \
+                 makefinal,ckl,postsort,getrrsz,sender)                   \
 { adns_r_##code & adns_rrt_reprmask, rrt,fmt,TYPESZ_M(memb), makefinal,           \
-    printer,parser,comparer,qdpl,postsort,getrrsz,sender }
+    printer,parser,comparer,ckl,postsort,getrrsz,sender }
 
 static const typeinfo typeinfos[] = {
 /* Must be in ascending order of rrtype ! */
@@ -1728,15 +1657,16 @@ DEEP_TYPE(txt,    "TXT",   0,   manyistr,pa_txt,     0,        cs_txt        ),
 DEEP_TYPE(rp_raw, "RP",   "raw",strpair, pa_rp,      0,        cs_rp         ),
 FLAT_TYPE(aaaa,   "AAAA",  0,   in6addr, pa_in6addr, di_in6addr,cs_in6addr   ),
 XTRA_TYPE(srv_raw,"SRV",  "raw",srvraw , pa_srvraw,  di_srv,   cs_srvraw,
-                                     mf_srvraw, qdpl_srv, postsort_srv, 0, 0),
+                                      mf_srvraw, ckl_srv, postsort_srv, 0, 0),
 
 XTRA_TYPE(addr,   "A",  "addr", addr,    pa_addr,    di_addr,  cs_addr,
-                            mf_flat, adns__qdpl_normal, 0, gsz_addr, qs_addr),
+                           mf_flat, adns__ckl_hostname, 0, gsz_addr, qs_addr),
 DEEP_TYPE(ns,     "NS", "+addr",hostaddr,pa_hostaddr,di_hostaddr,cs_hostaddr ),
-DEEP_TYPE(ptr,    "PTR","checked",str,   pa_ptr,     0,        cs_domain     ),
+XTRA_TYPE(ptr,    "PTR","checked",str,   pa_ptr,     0,        cs_domain,
+                                                    mf_str, ckl_ptr, 0, 0, 0),
 DEEP_TYPE(mx,     "MX", "+addr",inthostaddr,pa_mx,   di_mx,    cs_inthostaddr),
 XTRA_TYPE(srv,    "SRV","+addr",srvha,   pa_srvha,   di_srv,   cs_srvha,
-                                      mf_srvha, qdpl_srv, postsort_srv, 0, 0),
+                                       mf_srvha, ckl_srv, postsort_srv, 0, 0),
 
 DEEP_TYPE(soa,    "SOA","822",  soa,     pa_soa,     0,        cs_soa        ),
 DEEP_TYPE(rp,     "RP", "822",  strpair, pa_rp,      0,        cs_rp         ),
@@ -1744,7 +1674,7 @@ DEEP_TYPE(rp,     "RP", "822",  strpair, pa_rp,      0,        cs_rp         ),
 
 static const typeinfo tinfo_addrsub =
 XTRA_TYPE(none,          "<addr>","sub",addr,   pa_addr,    0,        cs_addr,
-                                  mf_flat, adns__qdpl_normal, 0, gsz_addr, 0);
+                                 mf_flat, adns__ckl_hostname, 0, gsz_addr, 0);
 
 static const typeinfo typeinfo_unknown=
 DEEP_TYPE(unknown,0, "unknown",byteblock,pa_opaque,  0,        cs_opaque     );