chiark / gitweb /
Add a type hook for reporting the output record size.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 14 May 2014 01:01:27 +0000 (02:01 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 14 May 2014 01:01:27 +0000 (02:01 +0100)
Otherwise adns_rr_info doesn't work properly.

src/general.c
src/internal.h
src/query.c
src/setup.c
src/types.c

index facc0b5b8d433ce1465848e291393e697b93d010..cbe735a29040b2bc634a20c3373085ce052241db 100644 (file)
@@ -222,7 +222,7 @@ adns_status adns_rr_info(adns_rrtype type,
 
   if (rrtname_r) *rrtname_r= typei->rrtname;
   if (fmtname_r) *fmtname_r= typei->fmtname;
-  if (len_r) *len_r= typei->rrsz;
+  if (len_r) *len_r= typei->getrrsz ? typei->getrrsz(type) : typei->rrsz;
 
   if (!datap) return adns_s_ok;
   
index a9ea879e6757af39d489c678cccf8b1f5d99d356..f8f34c7cd3ade2deaea86dea414e04fdd0967e65 100644 (file)
@@ -205,6 +205,11 @@ typedef struct typeinfo {
    * stuff.)  May be 0 to mean nothing needs to be done.
    */
 
+  int (*getrrsz)(adns_rrtype type);
+  /* Return the output resource-record element size; if this is null, then
+   * the rrsz member can be used.
+   */
+
   void (*query_send)(adns_query qu, struct timeval now);
   /* Send the query to nameservers, and hook it into the appropriate queue.
    * Normal behaviour is to call adns__query_send, but this can be overridden
index 8944b2f3c67d527d30b1ccba959a500e3d68a6f8..30108f2a6b7a24e2e3f8196ce8dbb0f4d72f83c7 100644 (file)
@@ -83,7 +83,7 @@ static adns_query query_alloc(adns_state ads,
   qu->answer->expires= -1;
   qu->answer->nrrs= 0;
   qu->answer->rrs.untyped= 0;
-  qu->answer->rrsz= typei->rrsz;
+  qu->answer->rrsz= typei->getrrsz ? typei->getrrsz(type) : typei->rrsz;
 
   return qu;
 }
index a264d15ea83aa61260a1c6300b0b0beebcfc9825..21db53cd1db95d80c2b968ab9dedb7ada4c00a7d 100644 (file)
@@ -616,6 +616,7 @@ static int init_finish(adns_state ads) {
     if (ads->logfn && ads->iflags & adns_if_debug)
       adns__lprintf(ads,"adns: no nameservers, using IPv4 localhost\n");
     memset(&sin, 0, sizeof(sin));
+    sin.sin_family = AF_INET;
     sin.sin_port = htons(DNS_PORT);
     sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
     addserver(ads,(struct sockaddr *)&sin, sizeof(sin));
index 93fb4fc33f87ba61d177501762589d507fbfbe9d..c0183c91507c5610088f4ff568f8f3130bfa1ae4 100644 (file)
@@ -51,7 +51,7 @@
  * _txt                       (pa)
  * _inaddr                    (pa,cs,di, +search_sortlist, dip_genaddr)
  * _in6addr                   (pa,cs,di)
- * _addr                      (pap,pa,di,csp,cs,qs,  +search_sortlist_sa,
+ * _addr                      (pap,pa,di,csp,cs,gsz,qs,  +search_sortlist_sa,
  *                             dip_sockaddr, rrtypes)
  * _domain                    (pap)
  * _host_raw                  (pa)
@@ -335,8 +335,8 @@ static adns_status cs_in6addr(vbuf *vb, const void *datap) {
 }
 
 /*
- * _addr   (pap,pa,di,csp,cs,qs, +search_sortlist_sa, dip_sockaddr,
- *             addr_rrtypes, addr_rrsz)
+ * _addr   (pap,pa,di,csp,cs,gsz,qs, +search_sortlist_sa, dip_sockaddr,
+ *             addr_rrtypes)
  */
 
 /* About CNAME handling in addr queries.
@@ -487,6 +487,8 @@ static void addr_rrtypes(adns_state ads, adns_rrtype type,
   adns_rrtype qtf = type & adns__qtf_deref;
   adns_queryflags permitaf = 0, hackaf = 0;
 
+  if (!(qf & (adns_qf_ipv4_only | adns_qf_ipv6_only)))
+    qf |= adns_qf_ipv4_only | adns_qf_ipv6_only;
   if (!(type & adns__qtf_bigaddr) || !(type & adns__qtf_manyaf))
     qf = (qf & adns__qf_afmask) | adns_qf_ipv4_only;
   else if (ads->iflags & adns_if_afmask) {
@@ -500,16 +502,15 @@ static void addr_rrtypes(adns_state ads, adns_rrtype type,
       qf &= hackaf | permitaf | ~adns__qf_afmask;
   }
 
-
   if (qf & adns_qf_ipv4_only) rrty[n++] = adns_r_a | qtf;
   if (qf & adns_qf_ipv6_only) rrty[n++] = adns_r_aaaa | qtf;
 
   *nrrty = n;
 }
 
-static size_t addr_rrsz(adns_query qu)
+static int gsz_addr(adns_rrtype type)
 {
-  return qu->answer->type & adns__qtf_bigaddr ?
+  return type & adns__qtf_bigaddr ?
     sizeof(adns_rr_addr) : sizeof(adns_rr_addr_v4only);
 }
 
@@ -546,9 +547,6 @@ static void addr_subqueries(adns_query qu, struct timeval now,
     ~(adns_qf_search);
   qcontext ctx;
 
-  if (!(qu->answer->type & adns__qtf_bigaddr))
-    qu->answer->rrsz = sizeof(adns_rr_addr_v4only);
-
   /* This always makes child queries, even if there's only the one.  This
    * seems wasteful, but there's only one case where it'd be safe -- namely
    * IPv4-only -- and that's not the case I want to optimize.
@@ -854,7 +852,7 @@ static void icb_hostaddr(adns_query parent, adns_query child) {
   adns_rr_hostaddr *rrp= child->ctx.info.hostaddr;
   adns_state ads= parent->ads;
   adns_status st;
-  size_t addrsz = addr_rrsz(parent);
+  size_t addrsz = gsz_addr(parent->answer->type);
 
   st= cans->status == adns_s_nodata ? adns_s_ok : cans->status;
 
@@ -895,7 +893,7 @@ static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io,
   adns_queryflags nflags;
   adns_rrtype rrty[ADDR_MAXRRTYPES];
   size_t nrrty;
-  size_t addrsz = addr_rrsz(pai->qu);
+  size_t addrsz = gsz_addr(pai->qu->answer->type);
 
   dmstart= cbyte= *cbyte_io;
   st= pap_domain(pai, &cbyte, max, &rrp->host,
@@ -1688,14 +1686,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 }
+    mf_##memb, printer,parser,comparer, adns__qdpl_normal,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 }
+    mf_flat, printer,parser,comparer, adns__qdpl_normal,0,0,0 }
 #define XTRA_TYPE(code,rrt,fmt,memb,parser,comparer,printer,              \
-                 makefinal,qdpl,postsort,sender)                          \
+                 makefinal,qdpl,postsort,getrrsz,sender)                  \
 { adns_r_##code & adns_rrt_reprmask, rrt,fmt,TYPESZ_M(memb), makefinal,           \
-    printer,parser,comparer,qdpl,postsort,sender }
+    printer,parser,comparer,qdpl,postsort,getrrsz,sender }
 
 static const typeinfo typeinfos[] = {
 /* Must be in ascending order of rrtype ! */
@@ -1712,15 +1710,15 @@ 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),
+                                     mf_srvraw, qdpl_srv, postsort_srv, 0, 0),
 
 XTRA_TYPE(addr,   "A",  "addr", addr,    pa_addr,    di_addr,  cs_addr,
-                                      mf_flat, adns__qdpl_normal, 0, qs_addr),
+                            mf_flat, adns__qdpl_normal, 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     ),
 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),
+                                      mf_srvha, qdpl_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         ),