From e1d31292a9c52afb49d6dcbb5dc140289774f8c7 Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Wed, 14 May 2014 02:01:27 +0100 Subject: [PATCH] Add a type hook for reporting the output record size. Organization: Straylight/Edgeware From: Mark Wooding Otherwise adns_rr_info doesn't work properly. --- src/general.c | 2 +- src/internal.h | 5 +++++ src/query.c | 2 +- src/setup.c | 1 + src/types.c | 34 ++++++++++++++++------------------ 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/general.c b/src/general.c index facc0b5..cbe735a 100644 --- a/src/general.c +++ b/src/general.c @@ -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; diff --git a/src/internal.h b/src/internal.h index a9ea879..f8f34c7 100644 --- a/src/internal.h +++ b/src/internal.h @@ -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 diff --git a/src/query.c b/src/query.c index 8944b2f..30108f2 100644 --- a/src/query.c +++ b/src/query.c @@ -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; } diff --git a/src/setup.c b/src/setup.c index a264d15..21db53c 100644 --- a/src/setup.c +++ b/src/setup.c @@ -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)); diff --git a/src/types.c b/src/types.c index 93fb4fc..c0183c9 100644 --- a/src/types.c +++ b/src/types.c @@ -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 ), -- [mdw]