X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=blobdiff_plain;f=src%2Fparse.c;h=099deb7884ff396ce2826b5c768a94bb30842f68;hp=bf04d4d2ef089c85c90fd42d048cea1665ae6601;hb=3955725ceceb330041f8e7a27e6629a2e8a9b5ba;hpb=e576be5096ae358bebe2e9b6ad07c49f74aef616 diff --git a/src/parse.c b/src/parse.c index bf04d4d..099deb7 100644 --- a/src/parse.c +++ b/src/parse.c @@ -46,11 +46,12 @@ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len) { return 1; } -void adns__findlabel_start(findlabel_state *fls, - adns_state ads, int serv, +void adns__findlabel_start(findlabel_state *fls, adns_state ads, + int serv, adns_query qu, const byte *dgram, int dglen, int max, int dmbegin, int *dmend_rlater) { fls->ads= ads; + fls->qu= qu; fls->serv= serv; fls->dgram= dgram; fls->dglen= dglen; @@ -58,23 +59,23 @@ void adns__findlabel_start(findlabel_state *fls, fls->cbyte= dmbegin; fls->namelen= 0; fls->dmend_r= dmend_rlater; - fls->namelen_r= namelen_rlater; } -adns_status adns__findlabel_next(findlabel_state fls, +adns_status adns__findlabel_next(findlabel_state *fls, int *lablen_r, int *labstart_r) { int lablen, jumped; + const char *dgram; jumped= 0; + dgram= fls->dgram; for (;;) { - fls->cbyte += 2; - if (fls->cbyte > fls->dglen) goto x_truncated; - if (fls->cbyte > fls->max) goto x_serverfaulty; - GET_W(fls->cbyte-2,lablen); + if (fls->cbyte+2 > fls->dglen) goto x_truncated; + if (fls->cbyte+2 > fls->max) goto x_serverfaulty; + GET_W(fls->cbyte,lablen); if (!(lablen & 0x0c000)) break; if ((lablen & 0x0c000) != 0x0c000) return adns_s_unknownreply; if (jumped++) { - adns__diag(ads,fls->serv,fls->qu,"compressed datagram contains loop"); + adns__diag(fls->ads,fls->serv,fls->qu,"compressed datagram contains loop"); return adns_s_serverfaulty; } if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte; @@ -90,7 +91,6 @@ adns_status adns__findlabel_next(findlabel_state fls, if (fls->cbyte > fls->max) goto x_serverfaulty; } else { if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte; - if (fls->namelen_r) *(fls->namelen_r)= fls->namelen; } if (labstart_r) *labstart_r= fls->cbyte; *lablen_r= lablen; @@ -101,19 +101,19 @@ adns_status adns__findlabel_next(findlabel_state fls, return adns_s_ok; x_serverfaulty: - adns__diag(ads,fls->serv,fls->qu,"label in domain runs beyond end of domain"); + adns__diag(fls->ads,fls->serv,fls->qu,"label in domain runs beyond end of domain"); return adns_s_serverfaulty; } -adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, int flags, - const byte *dgram, int dglen, - int *cbyte_io, int max) { +adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, + vbuf *vb, int flags, + const byte *dgram, int dglen, int *cbyte_io, int max) { findlabel_state fls; - int cbyte, lablen, labstart, namelen, i, ch; + int lablen, labstart, i, ch; adns_status st; - ands__findlabel_start(&fls,ads,serv, dgram,dglen,max, *cbyte_io,cbyte_io); + adns__findlabel_start(&fls,ads, serv,qu, dgram,dglen,max, *cbyte_io,cbyte_io); vb->used= 0; for (;;) { st= adns__findlabel_next(&fls,&lablen,&labstart); @@ -121,9 +121,9 @@ adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, int flags, if (lablen<0) { vb->used=0; return adns_s_ok; } if (!lablen) break; if (vb->used) - if (!adns__vbuf_append(&qu->ans,".",1)) return adns_s_nolocalmem; + if (!adns__vbuf_append(vb,".",1)) return adns_s_nolocalmem; if (flags & adns_qf_anyquote) { - if (!vbuf__append_quoted1035(&qu->ans,dgram+labstart,lablen)) + if (!vbuf__append_quoted1035(vb,dgram+labstart,lablen)) return adns_s_nolocalmem; } else { if (!ctype_alpha(dgram[labstart])) return adns_s_invaliddomain; @@ -132,27 +132,21 @@ adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, int flags, if (ch != '-' && !ctype_alpha(ch) && !ctype_digit(ch)) return adns_s_invaliddomain; } - if (!adns__vbuf_append(&qu->ans,dgram+labstart,lablen)) + if (!adns__vbuf_append(vb,dgram+labstart,lablen)) return adns_s_nolocalmem; } } - if (!adns__vbuf_append(&qu->ans,"",1)) return adns_s_nolocalmem; + if (!adns__vbuf_append(vb,"",1)) return adns_s_nolocalmem; return adns_s_ok; } -adns_status adns__findrr(adns_state ads, 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) { - /* 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. +static adns_status findrr_intern(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 @@ -163,26 +157,20 @@ adns_status adns__findrr(adns_state ads, int serv, * 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. - * - * 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. - * - * If an error is returned then *type_r will be undefined too. */ findlabel_state fls, eo_fls; int cbyte; int tmp, rdlen, mismatch; - int max, lablen, labstart, namelen, ch; - int eo_max, eo_lablen, eo_labstart, eo_namelen, eo_ch; + int lablen, labstart, ch; + int eo_lablen, eo_labstart, eo_ch; adns_status st; cbyte= *cbyte_io; - ands__findlabel_start(&fls,ads,serv, dgram,dglen,dglen,cbyte,&cbyte); + adns__findlabel_start(&fls,qu->ads, serv,qu, dgram,dglen,dglen,cbyte,&cbyte); if (eo_dgram) { - ands__findlabel_start(&eo_fls,ads,serv, eo_dgram,eo_dglen,eo_dglen,eo_cbyte,0); + adns__findlabel_start(&eo_fls,qu->ads, -1,0, eo_dgram,eo_dglen,eo_dglen,eo_cbyte,0); mismatch= 0; } else { mismatch= 1; @@ -221,3 +209,27 @@ adns_status adns__findrr(adns_state ads, int serv, *type_r= -1; return 0;; } + +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) { + if (!ownermatchedquery_r) { + return findrr_intern(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, + 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, + dgram,dglen,cbyte_io, + type_r,class_r,rdlen_r,rdstart_r, + qu->cname_dgram,qu->cname_dglen,qu->cname_begin, + ownermatchedquery_r); + } +}