chiark / gitweb /
Implement SOA, RP, HINFO (but no mailbox quoting). Implement _finish.
authorian <ian>
Mon, 16 Nov 1998 00:15:19 +0000 (00:15 +0000)
committerian <ian>
Mon, 16 Nov 1998 00:15:19 +0000 (00:15 +0000)
Cancel children on error.

client/adnstest.c
src/adns.h
src/parse.c
src/query.c
src/setup.c
src/types.c

index d8003dcde676a467acd00c2e6c119556779903fa..6badc22510a7e9c37e621741bb542c57a07545cd 100644 (file)
@@ -38,14 +38,21 @@ static const adns_rrtype defaulttypes[]= {
   adns_r_a,
   adns_r_ns_raw,
   adns_r_cname,
+  adns_r_soa_raw,
   adns_r_ptr_raw,
+  adns_r_hinfo,
   adns_r_mx_raw,
   adns_r_txt,
   adns_r_rp_raw,
+  
   adns_r_addr,
   adns_r_ns,
-  adns_r_mx,
   adns_r_ptr,
+  adns_r_mx,
+  
+  adns_r_soa,
+  adns_r_rp,
+
   adns_r_none
 };
 
@@ -143,5 +150,7 @@ int main(int argc, char *const *argv) {
   }
 
   free(qus);
+  adns_finish(ads);
+  
   exit(0);
 }
index a87767a98be468d9c6c8110420b95bd1675a1a48..17e4014ad5552d1a3ceb66625a6f99f11f2623ac 100644 (file)
@@ -143,7 +143,7 @@ typedef struct {
 } adns_rr_hostaddr;
 
 typedef struct {
-  char *a, *b;
+  char *(array[2]);
 } adns_rr_strpair;
 
 typedef struct {
@@ -162,7 +162,11 @@ typedef struct {
 } adns_rr_intstr;
 
 typedef struct {
-  char *ns0, *rp;
+  adns_rr_intstr array[2];
+} adns_rr_intstrpair;
+
+typedef struct {
+  char *mname, *rname;
   unsigned long serial, refresh, retry, expire, minimum;
 } adns_rr_soa;
 
@@ -179,7 +183,8 @@ typedef struct {
     adns_rr_addr *addr;               /* addr */
     struct in_addr *inaddr;           /* a */
     adns_rr_hostaddr *hostaddr;       /* ns */
-    adns_rr_strpair *strpair;         /* hinfo ??fixme, rp, rp_raw */
+    adns_rr_intstrpair *intstrpair;   /* hinfo */
+    adns_rr_strpair *strpair;         /* rp, rp_raw */
     adns_rr_inthostaddr *inthostaddr; /* mx */
     adns_rr_intstr *intstr;           /* mx_raw */
     adns_rr_soa *soa;                 /* soa, soa_raw */
@@ -242,7 +247,7 @@ int adns_wait(adns_state ads,
 
 void adns_cancel(adns_query query);
 
-int adns_finish(adns_state);
+void adns_finish(adns_state);
 /* You may call this even if you have queries outstanding;
  * they will be cancelled.
  */
index f2521d66ffcfad4d2b8d7ff6f99d1b69255623e6..388d09a6d771a30dbe12275bb7084859545d6278 100644 (file)
@@ -31,7 +31,7 @@ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len) {
     for (i=0; i<len; i++) {
       ch= buf[i];
       if (ch == '.' || ch == '"' || ch == '(' || ch == ')' ||
-         ch == '@' || ch == ';' || ch == '$') {
+         ch == '@' || ch == ';' || ch == '$' || ch == '\\') {
        sprintf(qbuf,"\\%c",ch);
        break;
       } else if (ch <= ' ' || ch >= 127) {
@@ -41,7 +41,9 @@ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len) {
     }
     if (!adns__vbuf_append(vb,buf,i) || !adns__vbuf_append(vb,qbuf,strlen(qbuf)))
       return 0;
-    buf+= i; len-= i;
+    if (i<len) i++;
+    buf+= i;
+    len-= i;
   }
   return 1;
 }
index e90d45c85955f497fac368c5e703671aec5a60f2..5605b34aed59ac5eabed9215a9f1d78c2a898dc4 100644 (file)
@@ -210,9 +210,19 @@ void *adns__alloc_final(adns_query qu, size_t sz) {
   return rp;
 }
 
+static void cancel_children(adns_query qu) {
+  adns_query cqu, ncqu;
+
+  for (cqu= qu->children.head; cqu; cqu= ncqu) {
+    ncqu= cqu->siblings.next;
+    adns_cancel(cqu);
+  }
+  LIST_INIT(qu->children);
+}
+
 void adns__reset_cnameonly(adns_query qu) {
-  /* fixme: cancel children */
   assert(!qu->final_allocspace);
+  cancel_children(qu);
   qu->answer->nrrs= 0;
   qu->answer->rrs= 0;
   qu->interim_allocd= qu->answer->cname ? MEM_ROUND(strlen(qu->answer->cname)+1) : 0;
@@ -220,12 +230,8 @@ void adns__reset_cnameonly(adns_query qu) {
 
 static void free_query_allocs(adns_query qu) {
   allocnode *an, *ann;
-  adns_query cqu, ncqu;
 
-  for (cqu= qu->children.head; cqu; cqu= ncqu) {
-    ncqu= cqu->siblings.next;
-    adns_cancel(cqu);
-  }
+  cancel_children(qu);
   for (an= qu->allocations.head; an; an= ann) { ann= an->next; free(an); }
   adns__vbuf_free(&qu->vb);
 }
index 3852603a545db86eea168e01598f709e29e5450e..72c72d4f031eb1e52e0b00b6b8feb4d9f0105f69 100644 (file)
@@ -248,6 +248,16 @@ int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) {
   return r;
 }
 
-int adns_finish(adns_state ads) {
-  abort(); /* fixme */
+void adns_finish(adns_state ads) {
+  for (;;) {
+    if (ads->timew.head) adns_cancel(ads->timew.head);
+    else if (ads->childw.head) adns_cancel(ads->childw.head);
+    else if (ads->output.head) adns_cancel(ads->output.head);
+    else break;
+  }
+  close(ads->udpsocket);
+  if (ads->tcpsocket >= 0) close(ads->tcpsocket);
+  adns__vbuf_free(&ads->tcpsend);
+  adns__vbuf_free(&ads->tcprecv);
+  free(ads);
 }
index dc91fb06fb09c68de4b8f4adb6128cc55b41262b..2803d11e8690dc445da683a9a5718565d0c7275b 100644 (file)
 /*
  * order of sections:
  *
+ * _string                    (pap)
  * _textdata, _qstring        (csp)
  * _str                       (mf,cs)
- * _intstr                    (mf,cs)
+ * _intstr                    (mf,csp,cs)
  * _manyistr                  (mf,cs)
  * _txt                       (pa)
  * _inaddr                    (pa,dip,di)
  * _mx                        (pa,di)
  * _inthostaddr               (mf,cs)
  * _ptr                       (pa)
+ * _strpair                   (mf,cs)
+ * _intstrpair                (mf,cs)
+ * _hinfo                     (pa)
+ * _mailbox                   (pap)
+ * _rp                        (pa)
+ * _soa                       (pa,mf,cs)
  * _flat                      (mf)
  *
  * within each section:
  */
 
 /*
+ * _string               (pap)
  * _textdata, _qstring   (csp)
  */
 
+static adns_status pap_string(const parseinfo *pai, int *cbyte_io, int max,
+                             int *len_r, char **str_r) {
+  /* Neither len_r nor str_r may be null.
+   * End of datagram (overrun) is indicated by returning adns_s_invaliddata;
+   */
+  const byte *dgram= pai->dgram;
+  int l, cbyte;
+  char *str;
+
+  cbyte= *cbyte_io;
+
+  if (cbyte >= max) return adns_s_invaliddata;
+  GET_B(cbyte,l);
+  if (cbyte+l > max) return adns_s_invaliddata;
+  
+  str= adns__alloc_interim(pai->qu, l+1);
+  if (!str) R_NOMEM;
+  
+  str[l]= 0;
+  memcpy(str,dgram+cbyte,l);
+
+  *len_r= l;
+  *str_r= str;
+  *cbyte_io= cbyte+l;
+  
+  return adns_s_ok;
+}
+
 static adns_status csp_textdata(vbuf *vb, const char *dp, int len) {
   unsigned char ch;
   char buf[10];
@@ -74,8 +110,10 @@ static adns_status csp_textdata(vbuf *vb, const char *dp, int len) {
     ch= *dp++;
     if (ch >= 32 && ch <= 126 && ch != '"' && ch != '\\') {
       if (!adns__vbuf_append(vb,&ch,1)) R_NOMEM;
+    } else if (ch == '\\') {
+      CSP_ADDSTR("\\\\");
     } else {
-      sprintf(buf,"\\%02x",ch);
+      sprintf(buf,"\\x%02x",ch);
       CSP_ADDSTR(buf);
     }
   }
@@ -105,7 +143,7 @@ static adns_status cs_str(vbuf *vb, const void *datap) {
 }
 
 /*
- * _intstr  (mf,cs)
+ * _intstr  (mf,csp,cs)
  */
 
 static void mf_intstr(adns_query qu, void *datap) {
@@ -114,8 +152,7 @@ static void mf_intstr(adns_query qu, void *datap) {
   adns__makefinal_str(qu,&rrp->str);
 }
 
-static adns_status cs_intstr(vbuf *vb, const void *datap) {
-  const adns_rr_intstr *rrp= datap;
+static adns_status csp_intstr(vbuf *vb, const adns_rr_intstr *rrp) {
   char buf[10];
 
   sprintf(buf,"%u ",rrp->i);
@@ -123,6 +160,12 @@ static adns_status cs_intstr(vbuf *vb, const void *datap) {
   return csp_qstring(vb,rrp->str);
 }
 
+static adns_status cs_intstr(vbuf *vb, const void *datap) {
+  const adns_rr_intstr *rrp= datap;
+  
+  return csp_intstr(vb,rrp);
+}
+
 /*
  * _manyistr   (mf,cs)
  */
@@ -162,6 +205,7 @@ static adns_status pa_txt(const parseinfo *pai, int cbyte, int max, void *datap)
   adns_rr_intstr **rrp= datap, *table, *te;
   const byte *dgram= pai->dgram;
   int ti, tc, l, startbyte;
+  adns_status st;
 
   startbyte= cbyte;
   if (cbyte >= max) return adns_s_invaliddata;
@@ -169,6 +213,7 @@ static adns_status pa_txt(const parseinfo *pai, int cbyte, int max, void *datap)
   while (cbyte < max) {
     GET_B(cbyte,l);
     cbyte+= l;
+    tc++;
   }
   if (cbyte != max) return adns_s_invaliddata;
 
@@ -176,12 +221,8 @@ static adns_status pa_txt(const parseinfo *pai, int cbyte, int max, void *datap)
   if (!table) R_NOMEM;
 
   for (cbyte=startbyte, ti=0, te=table; ti<tc; ti++, te++) {
-    GET_B(cbyte,l);
-    te->str= adns__alloc_interim(pai->qu, l+1);
-    if (!te->str) R_NOMEM;
-    te->str[l]= 0;
-    memcpy(te->str,dgram+cbyte,l);
-    te->i= l;
+    st= pap_string(pai, &cbyte, max, &te->i, &te->str);
+    if (st) return st;
   }
   assert(cbyte == max);
 
@@ -650,6 +691,150 @@ static adns_status pa_ptr(const parseinfo *pai, int dmstart, int max, void *data
   return adns_s_ok;
 }
 
+/*
+ * _strpair   (mf,cs)
+ */
+
+static void mf_strpair(adns_query qu, void *datap) {
+  adns_rr_strpair *rrp= datap;
+
+  adns__makefinal_str(qu,&rrp->array[0]);
+  adns__makefinal_str(qu,&rrp->array[1]);
+}
+
+static adns_status cs_strpair(vbuf *vb, const void *datap) {
+  const adns_rr_strpair *rrp= datap;
+  adns_status st;
+
+  st= csp_qstring(vb,rrp->array[0]);  if (st) return st;
+  CSP_ADDSTR(" ");
+  st= csp_qstring(vb,rrp->array[1]);  if (st) return st;
+
+  return adns_s_ok;
+}
+
+/*
+ * _intstrpair   (mf,cs)
+ */
+
+static void mf_intstrpair(adns_query qu, void *datap) {
+  adns_rr_intstrpair *rrp= datap;
+
+  adns__makefinal_str(qu,&rrp->array[0].str);
+  adns__makefinal_str(qu,&rrp->array[1].str);
+}
+
+static adns_status cs_intstrpair(vbuf *vb, const void *datap) {
+  const adns_rr_intstrpair *rrp= datap;
+  adns_status st;
+
+  st= csp_intstr(vb,&rrp->array[0]);  if (st) return st;
+  CSP_ADDSTR(" ");
+  st= csp_intstr(vb,&rrp->array[1]);  if (st) return st;
+
+  return adns_s_ok;
+}
+
+/*
+ * _hinfo   (pa)
+ */
+
+static adns_status pa_hinfo(const parseinfo *pai, int cbyte, int max, void *datap) {
+  adns_rr_intstrpair *rrp= datap;
+  adns_status st;
+  int i;
+
+  for (i=0; i<2; i++) {
+    st= pap_string(pai, &cbyte, max, &rrp->array[i].i, &rrp->array[i].str);
+    if (st) return st;
+  }
+
+  if (cbyte != max) return adns_s_invaliddata;
+  
+  return adns_s_ok;
+}
+
+/*
+ * _mailbox   (pap)
+ */
+
+static adns_status pap_mailbox(const parseinfo *pai, int *cbyte_io, int max,
+                              char **mb_r) {
+  return pap_domain(pai, cbyte_io, max, mb_r, pdf_quoteok);
+  /* fixme: mailbox quoting */
+}
+
+/*
+ * _rp   (pa)
+ */
+
+static adns_status pa_rp(const parseinfo *pai, int cbyte, int max, void *datap) {
+  adns_rr_strpair *rrp= datap;
+  adns_status st;
+
+  st= pap_mailbox(pai, &cbyte, max, &rrp->array[0]);
+  if (st) return st;
+
+  st= pap_domain(pai, &cbyte, max, &rrp->array[1], pdf_quoteok);
+  if (st) return st;
+
+  if (cbyte != max) return adns_s_invaliddata;
+  return adns_s_ok;
+}
+
+/*
+ * _soa   (pa,mf,cs)
+ */
+
+static adns_status pa_soa(const parseinfo *pai, int cbyte, int max, void *datap) {
+  adns_rr_soa *rrp= datap;
+  const byte *dgram= pai->dgram;
+  adns_status st;
+  int msw, lsw, i;
+
+  st= pap_domain(pai, &cbyte, max, &rrp->mname,
+                pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
+  if (st) return st;
+
+  st= pap_mailbox(pai, &cbyte, max, &rrp->rname);
+  if (st) return st;
+
+  if (cbyte+20 != max) return adns_s_invaliddata;
+  
+  for (i=0; i<5; i++) {
+    GET_W(cbyte,msw);
+    GET_W(cbyte,lsw);
+    (&rrp->serial)[i]= (msw<<16) | lsw;
+  }
+
+  return adns_s_ok;
+}
+
+static void mf_soa(adns_query qu, void *datap) {
+  adns_rr_soa *rrp= datap;
+
+  adns__makefinal_str(qu,&rrp->mname);
+  adns__makefinal_str(qu,&rrp->rname);
+}
+
+static adns_status cs_soa(vbuf *vb, const void *datap) {
+  const adns_rr_soa *rrp= datap;
+  char buf[20];
+  int i;
+  adns_status st;
+  
+  st= csp_qstring(vb,rrp->mname);  if (st) return st;
+  CSP_ADDSTR(" ");
+  st= csp_qstring(vb,rrp->rname);  if (st) return st;
+
+  for (i=0; i<5; i++) {
+    sprintf(buf," %lu",(&rrp->serial)[i]);
+    CSP_ADDSTR(buf);
+  }
+
+  return adns_s_ok;
+}
+
 /*
  * _flat   (mf)
  */
@@ -677,28 +862,20 @@ static const typeinfo typeinfos[] = {
   FLAT_TYPE(a,       "A",     0,      inaddr,      pa_inaddr,    di_inaddr   ),
   DEEP_TYPE(ns_raw,  "NS",   "raw",   str,         pa_host_raw,  0           ),
   DEEP_TYPE(cname,   "CNAME", 0,      str,         pa_host_raw,  0           ),
-#if 0
   DEEP_TYPE(soa_raw, "SOA",  "raw",   soa,         pa_soa,       0           ),
-#endif                                                                              
   DEEP_TYPE(ptr_raw, "PTR",  "raw",   str,         pa_host_raw,  0           ),
-#if 0
-  DEEP_TYPE(hinfo,   "HINFO", 0,      strpair,     pa_hinfo,     0           ),
-#endif                                                                              
+  DEEP_TYPE(hinfo,   "HINFO", 0,      intstrpair,  pa_hinfo,     0           ),
   DEEP_TYPE(mx_raw,  "MX",   "raw",   intstr,      pa_mx_raw,    di_mx_raw   ),
   DEEP_TYPE(txt,     "TXT",   0,      manyistr,    pa_txt,       0           ),
-#if 0
   DEEP_TYPE(rp_raw,  "RP",   "raw",   strpair,     pa_rp,        0           ),
-#endif                                                                              
                                                                                     
   FLAT_TYPE(addr,    "A",  "addr",    addr,        pa_addr,      di_addr     ),
   DEEP_TYPE(ns,      "NS", "+addr",   hostaddr,    pa_hostaddr,  di_hostaddr ),
   DEEP_TYPE(ptr,     "PTR","checked", str,         pa_ptr,       0           ),
   DEEP_TYPE(mx,      "MX", "+addr",   inthostaddr, pa_mx,        di_mx       ),
                                                                           
-#if 0
-  DEEP_TYPE(soa,     "SOA","822",     soa,         pa_soa,        0          ),
-  DEEP_TYPE(rp,      "RP", "822",     strpair,     pa_rp,         0          ),
-#endif /* fixme - implement all types */
+  DEEP_TYPE(soa,     "SOA","822",     soa,         pa_soa,       0           ),
+  DEEP_TYPE(rp,      "RP", "822",     strpair,     pa_rp,        0           ),
 };
 
 const typeinfo *adns__findtype(adns_rrtype type) {