From: ian Date: Sat, 14 Nov 1998 16:41:40 +0000 (+0000) Subject: Halfway through A lookups; need to restructure pa_... argument passing. X-Git-Tag: abandon.1999-04-10.multithread~36 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=c7836bc9e8b0ed6a04e9008545e29de410d9693e;hp=8837244370251f16e8f41097d4cbe5ef0058038c;p=adns.git Halfway through A lookups; need to restructure pa_... argument passing. --- diff --git a/src/adns.h b/src/adns.h index 5b7aa03..8ad963b 100644 --- a/src/adns.h +++ b/src/adns.h @@ -140,7 +140,7 @@ typedef struct { adns_status astatus; int naddrs; /* temp fail => -1, perm fail => 0, s_ok => >0 */ adns_addr *addrs; -} adns_rr_dmaddr; +} adns_rr_hostaddr; typedef struct { char *a, *b; @@ -148,8 +148,8 @@ typedef struct { typedef struct { int i; - adns_rr_dmaddr dmaddr; -} adns_rr_intdmaddr; + adns_rr_hostaddr hostaddr; +} adns_rr_inthostaddr; typedef struct { /* Used both for mx_raw, in which case i is the preference and str the domain, @@ -174,15 +174,15 @@ typedef struct { union { void *untyped; unsigned char *bytes; - char *(*str); /* ns_raw, cname, ptr, ptr_raw */ - adns_rr_intstr *(*manyistr); /* txt (list of strings ends with i=-1, str=0) */ - adns_addr *addr; /* addr */ - struct in_addr *inaddr; /* a */ - adns_rr_dmaddr *dmaddr; /* ns */ - adns_rr_strpair *strpair; /* hinfo ??fixme, rp, rp_raw */ - adns_rr_intdmaddr *intdmaddr; /* mx */ - adns_rr_intstr *intstr; /* mx_raw */ - adns_rr_soa *soa; /* soa, soa_raw */ + char *(*str); /* ns_raw, cname, ptr, ptr_raw */ + adns_rr_intstr *(*manyistr); /* txt (list of strings ends with i=-1, str=0) */ + adns_addr *addr; /* addr */ + struct in_addr *inaddr; /* a */ + adns_rr_hostaddr *hostaddr; /* ns */ + adns_rr_strpair *strpair; /* hinfo ??fixme, rp, rp_raw */ + adns_rr_inthostaddr *inthostaddr; /* mx */ + adns_rr_intstr *intstr; /* mx_raw */ + adns_rr_soa *soa; /* soa, soa_raw */ } rrs; } adns_answer; diff --git a/src/internal.h b/src/internal.h index 09ba2fe..7b12237 100644 --- a/src/internal.h +++ b/src/internal.h @@ -80,6 +80,12 @@ typedef union { int dmaddr_index; } qcontext; +typedef struct { + adns_query qu; + const byte *dgram; + int serv, dglen, max, nsstart; +} parseinfo; + typedef struct { adns_rrtype type; const char *rrtname; @@ -97,9 +103,7 @@ typedef struct { * and will not be null-terminated by convstring. */ - adns_status (*parse)(adns_query qu, int serv, - const byte *dgram, int dglen, int cbyte, int max, - int nsstart, int *arstart_io, void *store_r); + adns_status (*parse)(const struct parseinfo *pai, int cbyte, void *store_r); /* Parse one RR, in dgram of length dglen, starting at cbyte and * extending until at most max. * @@ -108,9 +112,7 @@ typedef struct { * If there is an overrun which might indicate truncation, it should set * *rdstart to -1; otherwise it may set it to anything else positive. * - * nsstart is the offset of the authority section; *arstart_io is - * -1 or the offset of the additional section; if it is -1 then - * parse may set it to the correct offset. + * nsstart is the offset of the authority section. */ int (*diff_needswap)(const void *datap_a, const void *datap_b); @@ -452,29 +454,48 @@ adns_status adns__findrr(adns_query qu, int serv, const byte *dgram, int dglen, int *cbyte_io, int *type_r, int *class_r, int *rdlen_r, int *rdstart_r, int *ownermatchedquery_r); - /* Finds the extent and some of the contents of an RR in a datagram - * and does some checks. The datagram is *dgram, length dglen, and - * the RR starts at *cbyte_io (which is updated afterwards to point - * to the end of the RR). - * - * The type, class and RRdata length and start are returned iff - * the corresponding pointer variables are not null. type_r and - * class_r may not be null. - * - * If ownermatchedquery_r != 0 then the owner domain of this - * RR will be compared with that in the query (or, if the query - * has gone to a CNAME lookup, with the canonical name). - * In this case, *ownermatchedquery_r will be set to 0 or 1. - * The query datagram (or CNAME datagram) MUST be valid and not truncated. - * - * If there is truncation then *type_r will be set to -1 and - * *cbyte_io, *class_r, *rdlen_r, *rdstart_r and *eo_matched_r will be - * undefined. - * - * qu must obviously be non-null. - * - * If an error is returned then *type_r will be undefined too. - */ +/* Finds the extent and some of the contents of an RR in a datagram + * and does some checks. The datagram is *dgram, length dglen, and + * the RR starts at *cbyte_io (which is updated afterwards to point + * to the end of the RR). + * + * The type, class and RRdata length and start are returned iff + * the corresponding pointer variables are not null. type_r and + * class_r may not be null. + * + * If ownermatchedquery_r != 0 then the owner domain of this + * RR will be compared with that in the query (or, if the query + * has gone to a CNAME lookup, with the canonical name). + * In this case, *ownermatchedquery_r will be set to 0 or 1. + * The query datagram (or CNAME datagram) MUST be valid and not truncated. + * + * If there is truncation then *type_r will be set to -1 and + * *cbyte_io, *class_r, *rdlen_r, *rdstart_r and *eo_matched_r will be + * undefined. + * + * qu must obviously be non-null. + * + * If an error is returned then *type_r will be undefined too. + */ + +static adns_status findrr_anychk(adns_query qu, int serv, + const byte *dgram, int dglen, int *cbyte_io, + int *type_r, int *class_r, int *rdlen_r, int *rdstart_r, + const byte *eo_dgram, int eo_dglen, int eo_cbyte, + int *eo_matched_r); +/* Like adns__findrr_checked, except that the datagram and + * owner to compare with can be specified explicitly. + * + * If the caller thinks they know what the owner of the RR ought to + * be they can pass in details in eo_*: this is another (or perhaps + * the same datagram), and a pointer to where the putative owner + * starts in that datagram. In this case *eo_matched_r will be set + * to 1 if the datagram matched or 0 if it did not. Either + * both eo_dgram and eo_matched_r must both be non-null, or they + * must both be null (in which case eo_dglen and eo_cbyte will be ignored). + * The eo datagram and contained owner domain MUST be valid and + * untruncated. + */ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len); diff --git a/src/parse.c b/src/parse.c index 722d9e4..bb08883 100644 --- a/src/parse.c +++ b/src/parse.c @@ -146,24 +146,11 @@ adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, return adns_s_ok; } -static adns_status findrr_intern(adns_query qu, int serv, +static adns_status findrr_anychk(adns_query qu, int serv, const byte *dgram, int dglen, int *cbyte_io, int *type_r, int *class_r, int *rdlen_r, int *rdstart_r, const byte *eo_dgram, int eo_dglen, int eo_cbyte, int *eo_matched_r) { - /* Like adns__findrr_checked, except that the datagram to compare - * with can be specified explicitly. - * - * If the caller thinks they know what the owner of the RR ought to - * be they can pass in details in eo_*: this is another (or perhaps - * the same datagram), and a pointer to where the putative owner - * starts in that datagram. In this case *eo_matched_r will be set - * to 1 if the datagram matched or 0 if it did not. Either - * both eo_dgram and eo_matched_r must both be non-null, or they - * must both be null (in which case eo_dglen and eo_cbyte will be ignored). - * The eo datagram and contained owner domain MUST be valid and - * untruncated. - */ findlabel_state fls, eo_fls; int cbyte; @@ -222,18 +209,18 @@ adns_status adns__findrr(adns_query qu, int serv, int *type_r, int *class_r, int *rdlen_r, int *rdstart_r, int *ownermatchedquery_r) { if (!ownermatchedquery_r) { - return findrr_intern(qu,serv, + return findrr_anychk(qu,serv, dgram,dglen,cbyte_io, type_r,class_r,rdlen_r,rdstart_r, 0,0,0, 0); } else if (!qu->cname_dgram) { - return findrr_intern(qu,serv, + return findrr_anychk(qu,serv, dgram,dglen,cbyte_io, type_r,class_r,rdlen_r,rdstart_r, qu->query_dgram,qu->query_dglen,DNS_HDRSIZE, ownermatchedquery_r); } else { - return findrr_intern(qu,serv, + return findrr_anychk(qu,serv, dgram,dglen,cbyte_io, type_r,class_r,rdlen_r,rdstart_r, qu->cname_dgram,qu->cname_dglen,qu->cname_begin, diff --git a/src/types.c b/src/types.c index 0f5e547..8993451 100644 --- a/src/types.c +++ b/src/types.c @@ -58,9 +58,9 @@ static adns_status cs_inaddr(vbuf *vb, const void *datap) { static adns_status pa_addr(adns_query qu, int serv, const byte *dgram, int dglen, int cbyte, int max, - int nsstart, int *arstart_io, void *datap) { + void *datap) { adns_addr *storeto= datap; - + if (max-cbyte != 4) return adns_s_invaliddata; storeto->len= sizeof(storeto->addr.inet); memset(&storeto->addr,0,sizeof(storeto->addr.inet)); @@ -149,6 +149,102 @@ static adns_status pa_mx_raw(adns_query qu, int serv, return adns_s_ok; } + +static adns_status pap_findaddrs(adns_query qu, int serv, adns_rr_hostaddr *ha, + const byte *dgram, int dglen, int *cbyte_io, + int dmstart, int count) { + int rri, nrrs; + int type, class, rdlen, rdstart, ownermatched; + + for (rri=0, nrrs=-1; rrivb.used= 0; + nrrs= 0; + } + if (!adns__vbuf_ensure(&qu->vb,qu->vb.used+sizeof(adns_addr))) + return adns_s_nolocalmem; + st= pa_addr(qu,serv, dgram,dglen, rdstart,rdstart+rdlen, + qu->vb.buf + qu->vb.used); + if (st) return st; + qu->vb.used += sizeof(adns_addr); + nrrs++; + } + if (nrrs >= 0) { + ha->rrs= adns__alloc_interim(qu,qu->vb.used); + if (!ha->rrs) return adns_s_nolocalmem; + ha->nrrs= nrrs; + ha->astatus= adns_s_ok; + } + return adns_s_ok; +} + +static adns_status pap_hostaddr(adns_query qu, int serv, + const byte *dgram, int dglen, int *cbyte_io, int max, + int nsstart, int nscount, int arcount, void *datap) { + adns_rr_hostaddr **rrp= datap; + adns_status st; + int dmstart, cbyte; + + dmstart= cbyte= *cbyte_io; + st= pap_domain(qu,serv, + qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0, + dgram,dglen,&cbyte,max,&rrp->dm); + if (st) return st; + *cbyte_io= cbyte; + + rrp->astatus= adns_s_ok; + rrp->naddrs= -1; + rrp->addrs= 0; + + cbyte= nsstart; + + st= pap_findaddrs(qu, rrp, dgram,dglen,&cbyte, dmstart); + if (st) return st; + if (rrp->naddrs != -1) return adns_s_ok; + + st= pap_findaddrs(qu, rrp, dgram,dglen,&cbyte, dmstart); + if (st) return st; + if (rrp->naddrs != -1) return adns_s_ok; +} + +static adns_status pa_hostaddr(adns_query qu, int serv, + const byte *dgram, int dglen, int cbyte, int max, + int nsstart, void *datap) { + adns_rr_hostaddr **rrp= datap; + adns_status st; + int dmstart; + + dmstart= cbyte; + st= pap_domain(qu,serv, + qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0, + dgram,dglen,&cbyte,max,&rrp->dm); + if (st) return st; + if (cbyte != max) return adns_s_invaliddata; + + rrp->astatus= adns_s_ok; + rrp->naddrs= -1; + rrp->addrs= 0; + + cbyte= nsstart; + + st= pap_findaddrs(qu, rrp, dgram,dglen, dmstart,&cbyte); + if (st) return st; + if (rrp->naddrs != -1) return adns_s_ok; + + st= pap_findaddrs(qu, rrp, dgram,dglen, dmstart,&cbyte); + if (st) return st; + if (rrp->naddrs != -1) return adns_s_ok; + + assert(!"additional section didn't have required data"); +} + static int di_mx_raw(const void *datap_a, const void *datap_b) { const adns_rr_intstr *ap= datap_a, *bp= datap_b; @@ -296,27 +392,27 @@ static const typeinfo typeinfos[] = { /* Must be in ascending order of rrtype ! */ /* rr type code rrt fmt mem.mgmt member parser comparer */ - { adns_r_a, "A", 0, FLAT_MEMB(inaddr), pa_inaddr, di_inaddr }, - { adns_r_ns_raw, "NS", "raw", DEEP_MEMB(str), pa_host_raw, 0 }, - { adns_r_cname, "CNAME", 0, DEEP_MEMB(str), pa_host_raw, 0 }, -#if 0 /*fixme*/ - { adns_r_soa_raw, "SOA", "raw", DEEP_MEMB(soa), pa_soa, 0 }, -#endif - { adns_r_ptr_raw, "PTR", "raw", DEEP_MEMB(str), pa_host_raw, 0 }, -#if 0 /*fixme*/ - { adns_r_hinfo, "HINFO", 0, DEEP_MEMB(strpair), pa_hinfo, 0 }, -#endif - { adns_r_mx_raw, "MX", "raw", DEEP_MEMB(intstr), pa_mx_raw, di_mx_raw }, - { adns_r_txt, "TXT", 0, DEEP_MEMB(manyistr), pa_txt, 0 }, -#if 0 /*fixme*/ - { adns_r_rp_raw, "RP", "raw", DEEP_MEMB(strpair), pa_rp, 0 }, -#endif - - { adns_r_addr, "A", "addr", FLAT_MEMB(addr), pa_addr, di_addr }, -#if 0 /*fixme*/ - { adns_r_ns, "NS", "+addr", DEEP_MEMB(dmaddr), pa_dmaddr, di_dmaddr }, - { adns_r_ptr, "PTR","checked", DEEP_MEMB(str), pa_ptr, 0 }, - { adns_r_mx, "MX", "+addr", DEEP_MEMB(intdmaddr), pa_mx, di_mx }, + { adns_r_a, "A", 0, FLAT_MEMB(inaddr), pa_inaddr, di_inaddr }, + { adns_r_ns_raw, "NS", "raw", DEEP_MEMB(str), pa_host_raw, 0 }, + { adns_r_cname, "CNAME", 0, DEEP_MEMB(str), pa_host_raw, 0 }, +#if 0 /*fixme*/ + { adns_r_soa_raw, "SOA", "raw", DEEP_MEMB(soa), pa_soa, 0 }, +#endif + { adns_r_ptr_raw, "PTR", "raw", DEEP_MEMB(str), pa_host_raw, 0 }, +#if 0 /*fixme*/ + { adns_r_hinfo, "HINFO", 0, DEEP_MEMB(strpair), pa_hinfo, 0 }, +#endif + { adns_r_mx_raw, "MX", "raw", DEEP_MEMB(intstr), pa_mx_raw, di_mx_raw }, + { adns_r_txt, "TXT", 0, DEEP_MEMB(manyistr), pa_txt, 0 }, +#if 0 /*fixme*/ + { adns_r_rp_raw, "RP", "raw", DEEP_MEMB(strpair), pa_rp, 0 }, +#endif + + { adns_r_addr, "A", "addr", FLAT_MEMB(addr), pa_addr, di_addr }, + { adns_r_ns, "NS", "+addr", DEEP_MEMB(dmaddr), pa_hostaddr, di_hostaddr }, +#if 0 /*fixme*/ + { adns_r_ptr, "PTR","checked", DEEP_MEMB(str), pa_ptr, 0 }, + { adns_r_mx, "MX", "+addr", DEEP_MEMB(intdmaddr), pa_mx, di_mx }, #endif #if 0 /*fixme*/