chiark / gitweb /
Do PTR checking (multiple PTRs allowed).
authorian <ian>
Sun, 15 Nov 1998 22:36:52 +0000 (22:36 +0000)
committerian <ian>
Sun, 15 Nov 1998 22:36:52 +0000 (22:36 +0000)
client/adnstest.c
src/event.c
src/general.c
src/internal.h
src/query.c
src/types.c

index b4c125a495bbcf9fbdc0416d58c9550109939b59..d8003dcde676a467acd00c2e6c119556779903fa 100644 (file)
@@ -45,6 +45,7 @@ static const adns_rrtype defaulttypes[]= {
   adns_r_addr,
   adns_r_ns,
   adns_r_mx,
   adns_r_addr,
   adns_r_ns,
   adns_r_mx,
+  adns_r_ptr,
   adns_r_none
 };
 
   adns_r_none
 };
 
@@ -73,8 +74,8 @@ int main(int argc, char *const *argv) {
     for (cp= argv[1]+1, ti=0; ti<tc; ti++) {
       types_a[ti]= strtoul(cp,&cp,10);
       if ((ch= *cp)) {
     for (cp= argv[1]+1, ti=0; ti<tc; ti++) {
       types_a[ti]= strtoul(cp,&cp,10);
       if ((ch= *cp)) {
-       if (ch != ':') {
-         fputs("usage: dtest [:<typenum>,...] [<domain> ...]",stderr);
+       if (ch != ',') {
+         fputs("usage: dtest [:<typenum>,...] [<domain> ...]\n",stderr);
          exit(4);
        }
        cp++;
          exit(4);
        }
        cp++;
index 8f3fb4c1b7ff354de827bfe33dbc31c1fd23bfd7..d42afbd15df2e9be1e806759f94063ef662cb1b1 100644 (file)
@@ -374,7 +374,7 @@ static int internal_check(adns_state ads,
   }
   LIST_UNLINK(ads->output,qu);
   *answer= qu->answer;
   }
   LIST_UNLINK(ads->output,qu);
   *answer= qu->answer;
-  if (context_r) *context_r= qu->context.ext;
+  if (context_r) *context_r= qu->ctx.ext;
   free(qu);
   return 0;
 }
   free(qu);
   return 0;
 }
index 211b6d20586a520aef2c672d4421912c17708d5c..eb03214b4ec6f4528f0e9946cbaaeb7b24b7ac5f 100644 (file)
@@ -217,7 +217,7 @@ static const struct sinfo {
   SINFO(  invalidanswerdomain, "Received syntactically invalid domain" ),
   SINFO(  nxdomain,            "No such domain"                        ),
   SINFO(  nodata,              "No such data"                          ),
   SINFO(  invalidanswerdomain, "Received syntactically invalid domain" ),
   SINFO(  nxdomain,            "No such domain"                        ),
   SINFO(  nodata,              "No such data"                          ),
-  SINFO(  invalidquerydomain,  "Domain syntactically invalid"          ),
+  SINFO(  invalidquerydomain,  "Query domain invalid"                  ),
   SINFO(  domaintoolong,       "Domain name too long"                  )
 };
 
   SINFO(  domaintoolong,       "Domain name too long"                  )
 };
 
index 33086f68c5350b43d7751cb83d3bd9fa2ca093bb..672e3a946d2661500d7323d6a57d63d895c16883 100644 (file)
@@ -50,6 +50,8 @@ typedef unsigned char byte;
 #define DNS_HDRSIZE 12
 #define DNS_CLASS_IN 1
 
 #define DNS_HDRSIZE 12
 #define DNS_CLASS_IN 1
 
+#define DNS_INADDR_ARPA "in-addr", "arpa"
+
 typedef enum {
   rcode_noerror,
   rcode_formaterror,
 typedef enum {
   rcode_noerror,
   rcode_formaterror,
@@ -75,16 +77,6 @@ typedef struct {
   byte *buf;
 } vbuf;
 
   byte *buf;
 } vbuf;
 
-typedef union {
-  void *ext;
-  struct {
-    void (*callback)(adns_query parent, adns_query child);
-    union {
-      adns_rr_hostaddr *hostaddr;
-    } info;
-  } intern;
-} qcontext;
-
 typedef struct {
   adns_state ads;
   adns_query qu;
 typedef struct {
   adns_state ads;
   adns_query qu;
@@ -142,6 +134,15 @@ union maxalign {
   union maxalign *up;
 } data;
 
   union maxalign *up;
 } data;
 
+typedef struct {
+  void *ext;
+  void (*callback)(adns_query parent, adns_query child);
+  union {
+    adns_rr_addr ptr_parent_addr;
+    adns_rr_hostaddr *hostaddr;
+  } info;
+} qcontext;
+
 struct adns__query {
   adns_state ads;
   enum { query_udp, query_tcpwait, query_tcpsent, query_child, query_done } state;
 struct adns__query {
   adns_state ads;
   enum { query_udp, query_tcpwait, query_tcpsent, query_child, query_done } state;
@@ -179,7 +180,8 @@ struct adns__query {
   int udpnextserver;
   unsigned long udpsent, tcpfailed; /* bitmap indexed by server */
   struct timeval timeout;
   int udpnextserver;
   unsigned long udpsent, tcpfailed; /* bitmap indexed by server */
   struct timeval timeout;
-  qcontext context;
+
+  qcontext ctx;
 
   /* Possible states:
    *
 
   /* Possible states:
    *
index 7c15a5bc8f418426ce986b8962aba4edd3420486..e90d45c85955f497fac368c5e703671aec5a60f2 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
+#include <string.h>
 
 #include <sys/time.h>
 
 
 #include <sys/time.h>
 
@@ -62,7 +63,7 @@ int adns__internal_submit(adns_state ads, adns_query *query_r,
   qu->udpnextserver= 0;
   qu->udpsent= qu->tcpfailed= 0;
   timerclear(&qu->timeout);
   qu->udpnextserver= 0;
   qu->udpsent= qu->tcpfailed= 0;
   timerclear(&qu->timeout);
-  memcpy(&qu->context,ctx,sizeof(qu->context));
+  memcpy(&qu->ctx,ctx,sizeof(qu->ctx));
 
   qu->answer->status= adns_s_ok;
   qu->answer->cname= 0;
 
   qu->answer->status= adns_s_ok;
   qu->answer->cname= 0;
@@ -120,6 +121,9 @@ int adns_submit(adns_state ads,
   if (!typei) return adns_s_notimplemented;
   
   ctx.ext= context;
   if (!typei) return adns_s_notimplemented;
   
   ctx.ext= context;
+  ctx.callback= 0;
+  memset(&ctx.info,0,sizeof(ctx.info));
+  
   r= gettimeofday(&now,0); if (r) return errno;
   id= 0;
 
   r= gettimeofday(&now,0); if (r) return errno;
   id= 0;
 
@@ -296,10 +300,9 @@ void adns__query_done(adns_query qu) {
   parent= qu->parent;
   if (parent) {
     LIST_UNLINK_PART(parent->children,qu,siblings.);
   parent= qu->parent;
   if (parent) {
     LIST_UNLINK_PART(parent->children,qu,siblings.);
-    qu->context.intern.callback(parent,qu);
+    qu->ctx.callback(parent,qu);
     free_query_allocs(qu);
     free(qu);
     free_query_allocs(qu);
     free(qu);
-    if (!parent->children.head) adns__query_done(parent);
   } else {
     makefinal_query(qu);
     LIST_LINK_TAIL(qu->ads->output,qu);
   } else {
     makefinal_query(qu);
     LIST_LINK_TAIL(qu->ads->output,qu);
index 0050b776ff76b2f3030b457f87ecf946a2a33d2a..dc91fb06fb09c68de4b8f4adb6128cc55b41262b 100644 (file)
@@ -46,6 +46,7 @@
  * _mx_raw                    (pa,di)
  * _mx                        (pa,di)
  * _inthostaddr               (mf,cs)
  * _mx_raw                    (pa,di)
  * _mx                        (pa,di)
  * _inthostaddr               (mf,cs)
+ * _ptr                       (pa)
  * _flat                      (mf)
  *
  * within each section:
  * _flat                      (mf)
  *
  * within each section:
@@ -235,7 +236,6 @@ static adns_status pa_addr(const parseinfo *pai, int cbyte, int max, void *datap
   storeto->len= sizeof(storeto->addr.inet);
   memset(&storeto->addr,0,sizeof(storeto->addr.inet));
   storeto->addr.inet.sin_family= AF_INET;
   storeto->len= sizeof(storeto->addr.inet);
   memset(&storeto->addr,0,sizeof(storeto->addr.inet));
   storeto->addr.inet.sin_family= AF_INET;
-  storeto->addr.inet.sin_port= 0;
   memcpy(&storeto->addr.inet.sin_addr,dgram+cbyte,4);
   return adns_s_ok;
 }
   memcpy(&storeto->addr.inet.sin_addr,dgram+cbyte,4);
   return adns_s_ok;
 }
@@ -351,13 +351,15 @@ static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha,
 }
 
 static void icb_hostaddr(adns_query parent, adns_query child) {
 }
 
 static void icb_hostaddr(adns_query parent, adns_query child) {
-  adns_rr_hostaddr *rrp= child->context.intern.info.hostaddr;
   adns_answer *cans= child->answer;
   adns_answer *cans= child->answer;
+  adns_rr_hostaddr *rrp= child->ctx.info.hostaddr;
 
   rrp->astatus= cans->status;
   rrp->naddrs= cans->nrrs;
   rrp->addrs= cans->rrs.addr;
   adns__transfer_interim(child, parent, rrp->addrs, rrp->naddrs*sizeof(adns_rr_addr));
 
   rrp->astatus= cans->status;
   rrp->naddrs= cans->nrrs;
   rrp->addrs= cans->rrs.addr;
   adns__transfer_interim(child, parent, rrp->addrs, rrp->naddrs*sizeof(adns_rr_addr));
+
+  if (!parent->children.head) adns__query_done(parent);
 }
 
 static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io,
 }
 
 static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io,
@@ -393,8 +395,9 @@ static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io,
                            adns_r_addr, adns_qf_quoteok_query);
   if (st) return st;
 
                            adns_r_addr, adns_qf_quoteok_query);
   if (st) return st;
 
-  ctx.intern.callback= icb_hostaddr;
-  ctx.intern.info.hostaddr= rrp;
+  ctx.ext= 0;
+  ctx.callback= icb_hostaddr;
+  ctx.info.hostaddr= rrp;
   st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr),
                            &pai->qu->vb, id,
                            adns_qf_quoteok_query, pai->now, 0, &ctx);
   st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr),
                            &pai->qu->vb, id,
                            adns_qf_quoteok_query, pai->now, 0, &ctx);
@@ -550,6 +553,103 @@ static adns_status cs_inthostaddr(vbuf *vb, const void *datap) {
   return csp_hostaddr(vb,&rrp->ha);
 }
 
   return csp_hostaddr(vb,&rrp->ha);
 }
 
+/*
+ * _ptr   (pa, +icb_ptr)
+ */
+
+static void icb_ptr(adns_query parent, adns_query child) {
+  adns_answer *cans= child->answer;
+  const adns_rr_addr *queried, *found;
+  int i;
+
+  if (cans->status == adns_s_nxdomain || cans->status == adns_s_nodata) {
+    adns__query_fail(parent,adns_s_inconsistent);
+    return;
+  } else if (cans->status) {
+    adns__query_fail(parent,cans->status);
+    return;
+  }
+
+  queried= &parent->ctx.info.ptr_parent_addr;
+  for (i=0, found=cans->rrs.addr; i<cans->nrrs; i++, found++) {
+    if (queried->len == found->len &&
+       !memcmp(&queried->addr,&found->addr,queried->len)) {
+      if (!parent->children.head) adns__query_done(parent);
+      return;
+    }
+  }
+
+  adns__query_fail(parent,adns_s_inconsistent);
+}
+
+static adns_status pa_ptr(const parseinfo *pai, int dmstart, int max, void *datap) {
+  static const char *(expectdomain[])= { DNS_INADDR_ARPA };
+  
+  char **rrp= datap;
+  adns_status st;
+  adns_rr_addr *ap;
+  findlabel_state fls;
+  char *ep;
+  byte ipv[4];
+  char labbuf[4];
+  int cbyte, i, lablen, labstart, l, id;
+  adns_query nqu;
+  qcontext ctx;
+
+  cbyte= dmstart;
+  st= pap_domain(pai, &cbyte, max, rrp,
+                pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
+  if (st) return st;
+  if (cbyte != max) return adns_s_invaliddata;
+
+  ap= &pai->qu->ctx.info.ptr_parent_addr;
+  if (!ap->len) {
+    adns__findlabel_start(&fls, pai->ads, -1, pai->qu,
+                         pai->qu->query_dgram, pai->qu->query_dglen,
+                         pai->qu->query_dglen, DNS_HDRSIZE, 0);
+    for (i=0; i<4; i++) {
+      st= adns__findlabel_next(&fls,&lablen,&labstart); assert(!st);
+      if (lablen<=0 || lablen>3) return adns_s_invalidquerydomain;
+      memcpy(labbuf, pai->qu->query_dgram + labstart, lablen);  labbuf[lablen]= 0;
+      ipv[3-i]= strtoul(labbuf,&ep,10);  if (*ep) return adns_s_invalidquerydomain;
+      if (lablen>1 && pai->qu->query_dgram[labstart]=='0')
+       return adns_s_invalidquerydomain;
+    }
+    for (i=0; i<sizeof(expectdomain)/sizeof(*expectdomain); i++) {
+      st= adns__findlabel_next(&fls,&lablen,&labstart); assert(!st);
+      l= strlen(expectdomain[i]);
+      if (lablen != l || memcmp(pai->qu->query_dgram + labstart, expectdomain[i], l))
+       return adns_s_invalidquerydomain;
+    }
+    st= adns__findlabel_next(&fls,&lablen,0); assert(!st);
+    if (lablen) return adns_s_invalidquerydomain;
+    
+    ap->len= sizeof(struct sockaddr_in);
+    memset(&ap->addr,0,sizeof(ap->addr.inet));
+    ap->addr.inet.sin_family= AF_INET;
+    ap->addr.inet.sin_addr.s_addr=
+      htonl((ipv[0]<<24) | (ipv[1]<<16) | (ipv[2]<<8) | (ipv[3]));
+  }
+
+  st= adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id,
+                           pai->dgram, pai->dglen, dmstart,
+                           adns_r_addr, adns_qf_quoteok_query);
+  if (st) return st;
+
+  ctx.ext= 0;
+  ctx.callback= icb_ptr;
+  memset(&ctx.info,0,sizeof(ctx.info));
+  st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr),
+                           &pai->qu->vb, id,
+                           adns_qf_quoteok_query, pai->now, 0, &ctx);
+  if (st) return st;
+
+  nqu->parent= pai->qu;
+  LIST_LINK_TAIL_PART(pai->qu->children,nqu,siblings.);
+  
+  return adns_s_ok;
+}
+
 /*
  * _flat   (mf)
  */
 /*
  * _flat   (mf)
  */
@@ -592,9 +692,7 @@ static const typeinfo typeinfos[] = {
                                                                                     
   FLAT_TYPE(addr,    "A",  "addr",    addr,        pa_addr,      di_addr     ),
   DEEP_TYPE(ns,      "NS", "+addr",   hostaddr,    pa_hostaddr,  di_hostaddr ),
                                                                                     
   FLAT_TYPE(addr,    "A",  "addr",    addr,        pa_addr,      di_addr     ),
   DEEP_TYPE(ns,      "NS", "+addr",   hostaddr,    pa_hostaddr,  di_hostaddr ),
-#if 0
   DEEP_TYPE(ptr,     "PTR","checked", str,         pa_ptr,       0           ),
   DEEP_TYPE(ptr,     "PTR","checked", str,         pa_ptr,       0           ),
-#endif
   DEEP_TYPE(mx,      "MX", "+addr",   inthostaddr, pa_mx,        di_mx       ),
                                                                           
 #if 0
   DEEP_TYPE(mx,      "MX", "+addr",   inthostaddr, pa_mx,        di_mx       ),
                                                                           
 #if 0