From: Mark Wooding Date: Tue, 10 Jun 2014 22:44:13 +0000 (+0100) Subject: src/types.c: Start on IPv6 support in adns_r_addr queries. X-Git-Tag: adns-1.5.0-rc0~65 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=commitdiff_plain;h=9d138734ee5af9b79ea81529f54971dbc60c968c src/types.c: Start on IPv6 support in adns_r_addr queries. The way addr queries work internally is now very different. The toplevel query is now `virtual', and exists to spawn subqueries for each applicable address type (currently hardcoded to A only, but this will change later). The toplevel query has a callback function which assembles its answer from the various child queries, and there's a collection of support machinery too. (Some of the bookkeeping done during this may seem unnecessary, but it will come in handy later.) Because more of the work is now done in internal query callbacks, some of the answers in the tests are reported in different order. See `Reentrancy: Avoid reentrant callbacks' for more detailed explanation of a similar change. Signed-off-by: Mark Wooding Signed-off-by: Ian Jackson --- diff --git a/regress/case-abbrevto.out b/regress/case-abbrevto.out index 0bc268b..cdccc4b 100644 --- a/regress/case-abbrevto.out +++ b/regress/case-abbrevto.out @@ -24,9 +24,9 @@ greenend.org.uk flags 0 type HINFO(-) ownflags=a: timeout; nrrs=0; cname=$; owne greenend.org.uk flags 0 type MX(raw) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 greenend.org.uk flags 0 type TXT(-) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 greenend.org.uk flags 0 type RP(raw) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 -greenend.org.uk flags 0 type A(addr) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 greenend.org.uk flags 0 type NS(+addr) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 greenend.org.uk flags 0 type MX(+addr) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 greenend.org.uk flags 0 type SOA(822) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 greenend.org.uk flags 0 type RP(822) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 +greenend.org.uk flags 0 type A(addr) ownflags=a: timeout; nrrs=0; cname=$; owner=$; ttl=604770 rc=0 diff --git a/regress/case-datapluscname.out b/regress/case-datapluscname.out index d5b36af..fa83e09 100644 --- a/regress/case-datapluscname.out +++ b/regress/case-datapluscname.out @@ -27,11 +27,11 @@ adns debug: ignoring RR with an unexpected owner 170.168.99.219.194.in-addr.arpa 170.99.219.194.in-addr.arpa flags 292 type MX(raw): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 170.99.219.194.in-addr.arpa flags 292 type TXT(-): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 170.99.219.194.in-addr.arpa flags 292 type RP(raw): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 -170.99.219.194.in-addr.arpa flags 292 type A(addr): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 170.99.219.194.in-addr.arpa flags 292 type NS(+addr): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 170.99.219.194.in-addr.arpa flags 292 type MX(+addr): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 170.99.219.194.in-addr.arpa flags 292 type SOA(822): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 170.99.219.194.in-addr.arpa flags 292 type RP(822): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 +170.99.219.194.in-addr.arpa flags 292 type A(addr): No such data; nrrs=0; cname=170.168.99.219.194.in-addr.arpa; owner=170.99.219.194.in-addr.arpa; ttl=0 170.99.219.194.in-addr.arpa flags 292 type PTR(checked): OK; nrrs=1; cname=$; owner=170.99.219.194.in-addr.arpa; ttl=171727 proxy.scoplife.gr 170.99.219.194.in-addr.arpa flags 292 type CNAME(-): OK; nrrs=1; cname=$; owner=170.99.219.194.in-addr.arpa; ttl=171726 diff --git a/regress/case-manyptrwrongrty.out b/regress/case-manyptrwrongrty.out index 6621afd..0a0d607 100644 --- a/regress/case-manyptrwrongrty.out +++ b/regress/case-manyptrwrongrty.out @@ -117,11 +117,11 @@ adns debug: TCP connected (NS=172.18.45.6) ns.asis.org.nz ns.bouquets.co.nz agate.co.nz -254.0.99.203.in-addr.arpa flags 292 type A(addr): No such data; nrrs=0; cname=$; owner=254.0.99.203.in-addr.arpa; ttl=539 254.0.99.203.in-addr.arpa flags 292 type NS(+addr): No such data; nrrs=0; cname=$; owner=254.0.99.203.in-addr.arpa; ttl=539 254.0.99.203.in-addr.arpa flags 292 type MX(+addr): No such data; nrrs=0; cname=$; owner=254.0.99.203.in-addr.arpa; ttl=540 254.0.99.203.in-addr.arpa flags 292 type SOA(822): No such data; nrrs=0; cname=$; owner=254.0.99.203.in-addr.arpa; ttl=540 254.0.99.203.in-addr.arpa flags 292 type RP(822): No such data; nrrs=0; cname=$; owner=254.0.99.203.in-addr.arpa; ttl=539 +254.0.99.203.in-addr.arpa flags 292 type A(addr): No such data; nrrs=0; cname=$; owner=254.0.99.203.in-addr.arpa; ttl=539 254.0.99.203.in-addr.arpa flags 292 type PTR(checked): Inconsistent resource records in DNS; nrrs=0; cname=$; owner=254.0.99.203.in-addr.arpa; ttl=86351 adns debug: reply not found, id 3151, query owner mail.safes.co.nz (NS=172.18.45.6) adns debug: reply not found, id 3152, query owner ns.bcc.co.nz (NS=172.18.45.6) diff --git a/regress/case-tcpallfail.out b/regress/case-tcpallfail.out index 799b0b5..4f11177 100644 --- a/regress/case-tcpallfail.out +++ b/regress/case-tcpallfail.out @@ -26,9 +26,9 @@ test.iwj.relativity.greenend.org.uk. flags 2 type HINFO(-): All nameservers fail test.iwj.relativity.greenend.org.uk. flags 2 type MX(raw): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 test.iwj.relativity.greenend.org.uk. flags 2 type TXT(-): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 test.iwj.relativity.greenend.org.uk. flags 2 type RP(raw): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 -test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 test.iwj.relativity.greenend.org.uk. flags 2 type NS(+addr): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 test.iwj.relativity.greenend.org.uk. flags 2 type MX(+addr): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 test.iwj.relativity.greenend.org.uk. flags 2 type SOA(822): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 test.iwj.relativity.greenend.org.uk. flags 2 type RP(822): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 +test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604800 rc=0 diff --git a/regress/case-tcpblock.out b/regress/case-tcpblock.out index dc628d3..34c8b65 100644 --- a/regress/case-tcpblock.out +++ b/regress/case-tcpblock.out @@ -25,9 +25,9 @@ test.iwj.relativity.greenend.org.uk. flags 2 type HINFO(-): DNS query timed out; test.iwj.relativity.greenend.org.uk. flags 2 type MX(raw): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 test.iwj.relativity.greenend.org.uk. flags 2 type TXT(-): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 test.iwj.relativity.greenend.org.uk. flags 2 type RP(raw): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 -test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 test.iwj.relativity.greenend.org.uk. flags 2 type NS(+addr): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 test.iwj.relativity.greenend.org.uk. flags 2 type MX(+addr): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 test.iwj.relativity.greenend.org.uk. flags 2 type SOA(822): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 test.iwj.relativity.greenend.org.uk. flags 2 type RP(822): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 +test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): DNS query timed out; nrrs=0; cname=$; owner=$; ttl=604770 rc=0 diff --git a/regress/case-tcpblockbrk.out b/regress/case-tcpblockbrk.out index 4b7e9bc..2b867e3 100644 --- a/regress/case-tcpblockbrk.out +++ b/regress/case-tcpblockbrk.out @@ -27,9 +27,9 @@ test.iwj.relativity.greenend.org.uk. flags 2 type HINFO(-): All nameservers fail test.iwj.relativity.greenend.org.uk. flags 2 type MX(raw): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 test.iwj.relativity.greenend.org.uk. flags 2 type TXT(-): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 test.iwj.relativity.greenend.org.uk. flags 2 type RP(raw): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 -test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 test.iwj.relativity.greenend.org.uk. flags 2 type NS(+addr): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 test.iwj.relativity.greenend.org.uk. flags 2 type MX(+addr): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 test.iwj.relativity.greenend.org.uk. flags 2 type SOA(822): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 test.iwj.relativity.greenend.org.uk. flags 2 type RP(822): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 +test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): All nameservers failed; nrrs=0; cname=$; owner=$; ttl=604798 rc=0 diff --git a/regress/case-tcpblockwr.out b/regress/case-tcpblockwr.out index 4b84e30..f050875 100644 --- a/regress/case-tcpblockwr.out +++ b/regress/case-tcpblockwr.out @@ -59,7 +59,6 @@ test.iwj.relativity.greenend.org.uk. flags 2 type HINFO(-): No such data; nrrs=0 test.iwj.relativity.greenend.org.uk. flags 2 type MX(raw): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type TXT(-): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type RP(raw): No such data; nrrs=0; cname=$; owner=$; ttl=59 -test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type NS(+addr): OK; nrrs=1; cname=$; owner=$; ttl=59 ns0.relativity.greenend.org.uk ok 0 ok "OK" ( INET 172.18.45.6 ) test.iwj.relativity.greenend.org.uk. flags 2 type MX(+addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 @@ -77,7 +76,6 @@ test.iwj.relativity.greenend.org.uk. flags 2 type HINFO(-): No such data; nrrs=0 test.iwj.relativity.greenend.org.uk. flags 2 type MX(raw): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type TXT(-): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type RP(raw): No such data; nrrs=0; cname=$; owner=$; ttl=59 -test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type NS(+addr): OK; nrrs=1; cname=$; owner=$; ttl=59 ns0.relativity.greenend.org.uk ok 0 ok "OK" ( INET 172.18.45.6 ) test.iwj.relativity.greenend.org.uk. flags 2 type MX(+addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 @@ -95,11 +93,13 @@ test.iwj.relativity.greenend.org.uk. flags 2 type HINFO(-): No such data; nrrs=0 test.iwj.relativity.greenend.org.uk. flags 2 type MX(raw): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type TXT(-): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type RP(raw): No such data; nrrs=0; cname=$; owner=$; ttl=59 -test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type NS(+addr): OK; nrrs=1; cname=$; owner=$; ttl=59 ns0.relativity.greenend.org.uk ok 0 ok "OK" ( INET 172.18.45.6 ) test.iwj.relativity.greenend.org.uk. flags 2 type MX(+addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type SOA(822): OK; nrrs=1; cname=$; owner=$; ttl=59 ns0.relativity.greenend.org.uk hostmaster@relativity.greenend.org.uk 42 3600 120 6604800 60 +test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 +test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 +test.iwj.relativity.greenend.org.uk. flags 2 type A(addr): No such data; nrrs=0; cname=$; owner=$; ttl=59 test.iwj.relativity.greenend.org.uk. flags 2 type RP(822): No such data; nrrs=0; cname=$; owner=$; ttl=60 rc=0 diff --git a/src/internal.h b/src/internal.h index 92b0d10..a95bf4d 100644 --- a/src/internal.h +++ b/src/internal.h @@ -151,6 +151,9 @@ typedef struct { adns_rrtype rev_rrtype; struct af_addr addr; } ptr; + struct { + unsigned want, have; + } addr; } tinfo; /* type-specific state for the query itself: zero-init if you * don't know better. */ diff --git a/src/transmit.c b/src/transmit.c index c2efdb5..be72cf2 100644 --- a/src/transmit.c +++ b/src/transmit.c @@ -120,7 +120,6 @@ adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, const char *p, *pe; adns_status st; - if (!((type^adns_r_addr) & adns_rrt_reprmask)) ads->nextid++; /* bodge */ st= mkquery_header(ads,vb,id_r,ol+2); if (st) return st; MKQUERY_START(vb); @@ -156,7 +155,6 @@ adns_status adns__mkquery_frdgram(adns_state ads, vbuf *vb, int *id_r, int lablen, labstart; adns_status st; - if (!((type^adns_r_addr) & adns_rrt_reprmask)) ads->nextid++; /* bodge */ st= mkquery_header(ads,vb,id_r,qd_dglen); if (st) return st; MKQUERY_START(vb); diff --git a/src/types.c b/src/types.c index cb343be..28db797 100644 --- a/src/types.c +++ b/src/types.c @@ -50,8 +50,9 @@ * _inaddr (pa,di,cs * +search_sortlist, dip_genaddr, csp_genaddr) * _in6addr (pa,di,cs) - * _addr (pa,di,div,csp,cs,gsz - * +search_sortlist_sa, dip_sockaddr) + * _addr (pa,di,div,csp,cs,gsz,qs + * +search_sortlst_sa, dip_sockaddr, + * addr_rrtypes, icb_addr) * _domain (pap,csp,cs) * _dom_raw (pa) * _host_raw (pa) @@ -342,9 +343,39 @@ static adns_status cs_in6addr(vbuf *vb, const void *datap) { } /* - * _addr (pa,di,div,csp,cs,gsz +search_sortlist_sa, dip_sockaddr) + * _addr (pa,di,div,csp,cs,gsz,qs + * +search_sortlist_sa, dip_sockaddr, addr_rrtypes, icb_addr) */ +static const typeinfo tinfo_addrsub; + +#define ADDR_RRTYPES(_) _(a) + +static const adns_rrtype addr_all_rrtypes[] = { +#define RRTY_CODE(ty) adns_r_##ty, + ADDR_RRTYPES(RRTY_CODE) +#undef RRTY_CODE +}; + +enum { +#define RRTY_INDEX(ty) addr__ri_##ty, + ADDR_RRTYPES(RRTY_INDEX) +#undef RRTY_INDEX + addr_nrrtypes, +#define RRTY_FLAG(ty) addr_rf_##ty = 1 << addr__ri_##ty, + ADDR_RRTYPES(RRTY_FLAG) + addr__rrty_hunoz +#undef RRTY_FLAG +}; + +static unsigned addr_rrtypeflag(adns_rrtype type) { + int i; + + type &= adns_rrt_typemask; + for (i=0; iflags & ~adns_qf_search) | qf_extra; + adns_rrtype qtf= qu->answer->type & adns__qtf_deref; + unsigned which= qu->ctx.tinfo.addr.want & ~qu->ctx.tinfo.addr.have; + qcontext ctx; + + memset(&ctx, 0, sizeof(ctx)); + ctx.callback= icb_addr; + for (i=0; iads, &qu->vb, &id, qd_dgram,qd_dglen, + DNS_HDRSIZE, addr_all_rrtypes[i], qf); + if (err) goto x_error; + err= adns__internal_submit(qu->ads, &cqu, qu, &tinfo_addrsub, + addr_all_rrtypes[i] | qtf, + &qu->vb, id, qf, now, &ctx); + if (err) goto x_error; + cqu->answer->rrsz= qu->answer->rrsz; + } + qu->state= query_childw; + LIST_LINK_TAIL(qu->ads->childw, qu); + return; + +x_error: + adns__query_fail(qu, err); +} + +static adns_status append_addrs(adns_query qu, size_t rrsz, + adns_rr_addr **dp, int *dlen, + const adns_rr_addr *sp, int slen) { + /* Append a vector of slen addr records, each of size rrsz, starting at ap, + * to a vector starting at *dp, of length *dlen. On successful completion, + * *dp and *dlen are updated. + */ + + size_t drrsz= *dlen*rrsz, srrsz= slen*rrsz; + byte *p; + + if (!slen) return adns_s_ok; + p= adns__alloc_interim(qu, drrsz + srrsz); + if (!p) R_NOMEM; + if (*dlen) { + memcpy(p, *dp, drrsz); + adns__free_interim(qu, *dp); + } + memcpy(p + drrsz, sp, srrsz); + *dlen += slen; + *dp= (adns_rr_addr *)p; + return adns_s_ok; +} + +static void propagate_ttl(adns_query to, adns_query from) + { if (to->expires > from->expires) to->expires= from->expires; } + +static adns_status copy_cname_from_child(adns_query parent, adns_query child) { + adns_answer *pans= parent->answer, *cans= child->answer; + size_t n= strlen(cans->cname) + 1; + + pans->cname= adns__alloc_preserved(parent, n); + if (!pans->cname) R_NOMEM; + memcpy(pans->cname, cans->cname, n); + return adns_s_ok; +} + +static void done_addr_type(adns_query qu, adns_rrtype type) { + unsigned f= addr_rrtypeflag(type); + assert(f); qu->ctx.tinfo.addr.have |= f; +} + +static void icb_addr(adns_query parent, adns_query child) { + adns_state ads= parent->ads; + adns_answer *pans= parent->answer, *cans= child->answer; + struct timeval now; + adns_status err; + + propagate_ttl(parent, child); + + if (cans->cname && !pans->cname) { + err= copy_cname_from_child(parent, child); + if (err) goto x_err; + } + + if ((parent->flags & adns_qf_search) && + !pans->cname && cans->status == adns_s_nxdomain) { + /* We're searching a list of suffixes, and the name doesn't exist. Try + * the next one. + */ + + adns__cancel_children(parent); + adns__free_interim(parent, pans->rrs.bytes); + pans->rrs.bytes= 0; pans->nrrs= 0; + if (gettimeofday(&now, 0)) goto x_gtod; + adns__search_next(ads, parent, now); + return; + } + + if (cans->status && cans->status != adns_s_nodata) + { err= cans->status; goto x_err; } + + assert(pans->rrsz == cans->rrsz); + err= append_addrs(parent, pans->rrsz, + &pans->rrs.addr, &pans->nrrs, + cans->rrs.addr, cans->nrrs); + if (err) goto x_err; + done_addr_type(parent, cans->type); + + if (parent->children.head) LIST_LINK_TAIL(ads->childw, parent); + else if (!pans->nrrs) adns__query_fail(parent, adns_s_nodata); + else adns__query_done(parent); + return; + +x_gtod: + adns__diag(ads, -1, parent, "gettimeofday failed: %s", strerror(errno)); + err= adns_s_systemfail; + goto x_err; + +x_err: + adns__query_fail(parent, err); +} + +static void qs_addr(adns_query qu, struct timeval now) { + if (!qu->ctx.tinfo.addr.want) { + qu->ctx.tinfo.addr.want= addr_rrtypes(qu->ads, qu->answer->type, + qu->flags); + qu->ctx.tinfo.addr.have= 0; + } + addr_subqueries(qu, now, 0, qu->query_dgram, qu->query_dglen); +} + /* * _domain (pap,csp,cs) * _dom_raw (pa) @@ -1309,7 +1483,7 @@ DEEP_TYPE(srv_raw,"SRV", "raw",srvraw , srvraw, srv, srvraw, .checklabel= ckl_srv, .postsort= postsort_srv), FLAT_TYPE(addr, "A", "addr", addr, addr, addr, addr, - .getrrsz= gsz_addr), + .getrrsz= gsz_addr, .query_send= qs_addr), DEEP_TYPE(ns, "NS", "+addr",hostaddr, hostaddr,hostaddr,hostaddr ), DEEP_TYPE(ptr, "PTR","checked",str, ptr, 0, domain, .checklabel= ckl_ptr), @@ -1321,6 +1495,10 @@ DEEP_TYPE(soa, "SOA","822", soa, soa, 0, soa ), DEEP_TYPE(rp, "RP", "822", strpair, rp, 0, rp ), }; +static const typeinfo tinfo_addrsub = +FLAT_TYPE(none, "","sub",addr, addr, 0, addr, + .getrrsz= gsz_addr); + static const typeinfo typeinfo_unknown= DEEP_TYPE(unknown,0, "unknown",byteblock,opaque, 0, opaque );