X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ftypes.c;h=754c237253d75f6628efac8c21029b20072546b2;hb=26e1c3d691b52d21a8bb52d9bf3f8e2b42ae6cfa;hp=d53fe3e05bdc4b5ccf2fcab58aa609eeb67a0f24;hpb=138722f000939e5a176b27d498c76681bdf04860;p=adns.git diff --git a/src/types.c b/src/types.c index d53fe3e..754c237 100644 --- a/src/types.c +++ b/src/types.c @@ -4,14 +4,14 @@ */ /* * This file is part of adns, which is - * Copyright (C) 1997-2000,2003,2006 Ian Jackson + * Copyright (C) 1997-2000,2003,2006,2014 Ian Jackson * Copyright (C) 1999-2000,2003,2006 Tony Finch * Copyright (C) 1991 Massachusetts Institute of Technology * (See the file INSTALL for full details.) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -20,8 +20,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program; if not, write to the Free Software Foundation. */ #include @@ -263,27 +262,26 @@ static adns_status pa_inaddr(const parseinfo *pai, int cbyte, static int search_sortlist(adns_state ads, int af, const void *ad) { const struct sortlist *slp; - const struct in6_addr *a6; - union gen_addr a; + struct in_addr a4; int i; int v6mappedp= 0; if (af == AF_INET6) { - a6= ad; + const struct in6_addr *a6= ad; if (IN6_IS_ADDR_V4MAPPED(a6)) { - a.v4.s_addr= htonl(((unsigned long)a6->s6_addr[12] << 24) | - ((unsigned long)a6->s6_addr[13] << 16) | - ((unsigned long)a6->s6_addr[14] << 8) | - ((unsigned long)a6->s6_addr[15] << 0)); + a4.s_addr= htonl(((unsigned long)a6->s6_addr[12] << 24) | + ((unsigned long)a6->s6_addr[13] << 16) | + ((unsigned long)a6->s6_addr[14] << 8) | + ((unsigned long)a6->s6_addr[15] << 0)); v6mappedp= 1; } } for (i=0, slp=ads->sortlist; insortlist && - !adns__addr_match_p(af,ad, slp->af,&slp->base,&slp->mask) && + !adns__addr_matches(af,ad, &slp->base,&slp->mask) && !(v6mappedp && - adns__addr_match_p(AF_INET,&a, slp->af,&slp->base,&slp->mask)); + adns__addr_matches(AF_INET,&a4, &slp->base,&slp->mask)); i++, slp++); return i; } @@ -311,7 +309,7 @@ static adns_status csp_genaddr(vbuf *vb, int af, const void *p) { memset(&a, 0, sizeof(a)); a.addr.sa.sa_family= af; - adns__sockaddr_inject(p, 0, &a.addr.sa); + adns__addr_inject(p, &a.addr); err= adns_addr2text(&a.addr.sa,0, buf,&len, 0); assert(!err); CSP_ADDSTR(buf); return adns_s_ok; @@ -366,7 +364,7 @@ enum { addr_nrrtypes, #define RRTY_FLAG(ty) addr_rf_##ty = 1 << addr__ri_##ty, ADDR_RRTYPES(RRTY_FLAG) - addr__rrty_hunoz + addr__rrty_eat_final_comma #undef RRTY_FLAG }; @@ -374,8 +372,10 @@ static unsigned addr_rrtypeflag(adns_rrtype type) { int i; type &= adns_rrt_typemask; - for (i=0; idgram; - int af, addrlen, salen; +static adns_status pap_addr(const parseinfo *pai, int in_rrty, size_t out_rrsz, + int *cbyte_io, int cbyte_max, adns_rr_addr *out) { + int in_addrlen; + int out_af, out_salen; struct in6_addr v6map; - const void *oaddr= dgram + *cbyte_io; - int avail= max - *cbyte_io; - int step= -1; - void *addrp= 0; - - switch (rrty) { - case adns_r_a: - if ((pai->qu->flags & adns_qf_ipv6_mapv4) && - (pai->qu->answer->type & adns__qtf_bigaddr)) { - if (avail < 4) return adns_s_invaliddata; - memset(v6map.s6_addr + 0, 0x00, 10); - memset(v6map.s6_addr + 10, 0xff, 2); - memcpy(v6map.s6_addr + 12, oaddr, 4); - oaddr= v6map.s6_addr; avail= sizeof(v6map.s6_addr); - if (step < 0) step= 4; - goto aaaa; - } - af= AF_INET; addrlen= 4; - addrp= &storeto->addr.inet.sin_addr; - salen= sizeof(storeto->addr.inet); - break; - case adns_r_aaaa: - aaaa: - af= AF_INET6; addrlen= 16; - addrp= storeto->addr.inet6.sin6_addr.s6_addr; - salen= sizeof(storeto->addr.inet6); - break; + + const void *use_addr= pai->dgram + *cbyte_io; + + switch (in_rrty) { + case adns_r_a: in_addrlen= 4; out_af= AF_INET; break; + case adns_r_aaaa: in_addrlen= 16; out_af= AF_INET6; break; + default: abort(); } - assert(addrp); - assert(offsetof(adns_rr_addr, addr) + salen <= rrsz); - if (addrlen < avail) return adns_s_invaliddata; - if (step < 0) step= addrlen; - *cbyte_io += step; - memset(&storeto->addr, 0, salen); - storeto->len= salen; - storeto->addr.sa.sa_family= af; - memcpy(addrp, oaddr, addrlen); + if ((*cbyte_io + in_addrlen) != cbyte_max) return adns_s_invaliddata; + if (out_af==AF_INET && + (pai->qu->flags & adns_qf_ipv6_mapv4) && + (pai->qu->answer->type & adns__qtf_bigaddr)) { + memset(v6map.s6_addr + 0, 0x00, 10); + memset(v6map.s6_addr + 10, 0xff, 2); + memcpy(v6map.s6_addr + 12, use_addr, 4); + use_addr= v6map.s6_addr; + out_af= AF_INET6; + } + + switch (out_af) { + case AF_INET: out_salen= sizeof(out->addr.inet); break; + case AF_INET6: out_salen= sizeof(out->addr.inet6); break; + default: abort(); + } + + assert(offsetof(adns_rr_addr, addr) + out_salen <= out_rrsz); + + memset(&out->addr, 0, out_salen); + out->len= out_salen; + out->addr.sa.sa_family= out_af; + adns__addr_inject(use_addr, &out->addr); + + *cbyte_io += in_addrlen; return adns_s_ok; } @@ -456,9 +452,8 @@ static adns_status pa_addr(const parseinfo *pai, int cbyte, } static int search_sortlist_sa(adns_state ads, const struct sockaddr *sa) { - union gen_addr a; - adns__sockaddr_extract(sa, &a, 0); - return search_sortlist(ads, sa->sa_family, &a); + const void *pa = adns__sockaddr_addr(sa); + return search_sortlist(ads, sa->sa_family, pa); } static int dip_sockaddr(adns_state ads, @@ -583,11 +578,11 @@ static adns_status addr_submit(adns_query parent, adns_query *query_r, * available record types. The memory management and callback rules are * the same as for adns__internal_submit. * - * Some differences: the query is linked onto the parent's children list - * before exit (though the parent's state is not changed, and it is not - * linked into the childw list queue); and we fiddle with the `tinfo' - * portion of the context structure (yes, modifying *ctx), since this is, - * in fact, the main purpose of this function. + * Some differences: the query is linked onto the parent's children + * list before exit (though the parent's state is not changed, and + * it is not linked into the childw list queue); and we set the + * `tinfo' portion of the context structure (yes, modifying *ctx), + * since this is, in fact, the main purpose of this function. */ adns_state ads= parent->ads; @@ -654,7 +649,7 @@ static void icb_addr(adns_query parent, adns_query child) { struct timeval now; adns_status err; adns_queryflags qf; - int id; + int id, r; propagate_ttl(parent, child); @@ -695,7 +690,7 @@ static void icb_addr(adns_query parent, adns_query child) { * settled on. */ adns__cancel_children(parent); - if (gettimeofday(&now, 0)) goto x_gtod; + r= gettimeofday(&now, 0); if (r) goto x_gtod; qf= adns__qf_addr_cname; if (!(parent->flags & adns_qf_cname_loose)) qf |= adns_qf_cname_forbid; addr_subqueries(parent, now, qf, child->vb.buf, child->vb.used); @@ -716,7 +711,7 @@ static void icb_addr(adns_query parent, adns_query child) { 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; + r= gettimeofday(&now, 0); if (r) goto x_gtod; adns__search_next(ads, parent, now); return; } @@ -738,6 +733,9 @@ static void icb_addr(adns_query parent, adns_query child) { return; x_gtod: + /* We have our own error handling, because adns__must_gettimeofday + * handles errors by calling adns_globalsystemfailure, which would + * reenter the query processing logic. */ adns__diag(ads, -1, parent, "gettimeofday failed: %s", strerror(errno)); err= adns_s_systemfail; goto x_err; @@ -1137,14 +1135,15 @@ static adns_status cs_inthost(vbuf *vb, const void *datap) { static adns_status ckl_ptr(adns_state ads, adns_queryflags flags, union checklabel_state *cls, qcontext *ctx, - int labnum, const char *label, int lablen) { + int labnum, const char *dgram, + int labstart, int lablen) { if (lablen) { - if (adns__revparse_label(&cls->ptr, labnum, label,lablen)) + if (!adns__revparse_label(&cls->ptr, labnum, dgram,labstart,lablen)) return adns_s_querydomainwrong; } else { - if (adns__revparse_done(&cls->ptr, labnum, - &ctx->tinfo.ptr.rev_rrtype, - &ctx->tinfo.ptr.addr)) + if (!adns__revparse_done(&cls->ptr, dgram, labnum, + &ctx->tinfo.ptr.rev_rrtype, + &ctx->tinfo.ptr.addr)) return adns_s_querydomainwrong; } return adns_s_ok; @@ -1152,7 +1151,7 @@ static adns_status ckl_ptr(adns_state ads, adns_queryflags flags, static void icb_ptr(adns_query parent, adns_query child) { adns_answer *cans= child->answer; - const struct af_addr *queried; + const adns_sockaddr *queried; const unsigned char *found; adns_state ads= parent->ads; int i; @@ -1167,8 +1166,8 @@ static void icb_ptr(adns_query parent, adns_query child) { queried= &parent->ctx.tinfo.ptr.addr; for (i=0, found=cans->rrs.bytes; inrrs; i++, found+=cans->rrsz) { - if (adns__genaddr_equal_p(queried->af,&queried->addr, - parent->ctx.tinfo.ptr.addr.af,found)) { + if (adns__addrs_equal_raw(&queried->sa, + parent->ctx.tinfo.ptr.addr.sa.sa_family,found)) { if (!parent->children.head) { adns__query_done(parent); return; @@ -1420,12 +1419,15 @@ static adns_status cs_soa(vbuf *vb, const void *datap) { static adns_status ckl_srv(adns_state ads, adns_queryflags flags, union checklabel_state *cls, qcontext *ctx, - int labnum, const char *label, int lablen) { - if (labnum < 2 && !(flags & adns_qf_quoteok_query)) { + int labnum, const char *dgram, + int labstart, int lablen) { + const char *label = dgram+labstart; + if (labnum < 2) { + if (flags & adns_qf_quoteok_query) return adns_s_ok; if (!lablen || label[0] != '_') return adns_s_querydomaininvalid; return adns_s_ok; } - return adns__ckl_hostname(ads, flags, cls, ctx, labnum, label, lablen); + return adns__ckl_hostname(ads,flags, cls,ctx, labnum, dgram,labstart,lablen); } static adns_status pap_srv_begin(const parseinfo *pai, int *cbyte_io, int max,