chiark / gitweb /
Compiles but does not link.
[adns.git] / src / parse.c
index bf04d4d..099deb7 100644 (file)
@@ -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);
+  }
+}