chiark / gitweb /
+ * Better checking of long domain names and labels in queries.
authorian <ian>
Wed, 1 Mar 2000 23:50:05 +0000 (23:50 +0000)
committerian <ian>
Wed, 1 Mar 2000 23:50:05 +0000 (23:50 +0000)
@@ -2,6 +2,8 @@
+  * Better checking of long domain names and labels in queries.
+  * Unfortunately, answer->owner may be null on error.  Documented.

changelog
client/adh-query.c
client/adnshost.h
src/adns.h
src/general.c
src/transmit.c

index f41efb6..155d177 100644 (file)
--- a/changelog
+++ b/changelog
@@ -2,6 +2,8 @@ adns (0.7) BETA; urgency=medium
 
   * README updated (from www home page).
   * Better reporting of unexpected or weird replies from nameserver.
 
   * README updated (from www home page).
   * Better reporting of unexpected or weird replies from nameserver.
+  * Better checking of long domain names and labels in queries.
+  * Unfortunately, answer->owner may be null on error.  Documented.
 
  --
 
 
  --
 
index bae71f4..cc5dc12 100644 (file)
@@ -89,6 +89,7 @@ void of_ptr(const struct optioninfo *oi, const char *arg) {
   if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg);
 
   prep_query(&qun,&quflags);
   if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg);
 
   prep_query(&qun,&quflags);
+  qun->owner= xstrsave(arg);
   r= adns_submit_reverse(ads,
                         (struct sockaddr*)&sa,
                         ov_type == adns_r_none ? adns_r_ptr : ov_type,
   r= adns_submit_reverse(ads,
                         (struct sockaddr*)&sa,
                         ov_type == adns_r_none ? adns_r_ptr : ov_type,
@@ -105,6 +106,7 @@ void query_do(const char *domain) {
   int quflags, r;
 
   prep_query(&qun,&quflags);
   int quflags, r;
 
   prep_query(&qun,&quflags);
+  qun->owner= xstrsave(domain);
   r= adns_submit(ads, domain,
                 ov_type == adns_r_none ? adns_r_addr : ov_type,
                 quflags,
   r= adns_submit(ads, domain,
                 ov_type == adns_r_none ? adns_r_addr : ov_type,
                 quflags,
@@ -145,8 +147,12 @@ static void print_ttl(struct query_node *qun, adns_answer *answer) {
   if (printf("%lu ",ttl) == EOF) outerr();
 }
 
   if (printf("%lu ",ttl) == EOF) outerr();
 }
 
+static const char *owner_show(struct query_node *qun, adns_answer *answer) {
+  return answer->owner ? answer->owner : qun->owner;
+}
+
 static void print_owner_ttl(struct query_node *qun, adns_answer *answer) {
 static void print_owner_ttl(struct query_node *qun, adns_answer *answer) {
-  if (qun->pqfr.show_owner) print_withspace(answer->owner);
+  if (qun->pqfr.show_owner) print_withspace(owner_show(qun,answer));
   print_ttl(qun,answer);
 }
 
   print_ttl(qun,answer);
 }
 
@@ -195,15 +201,15 @@ static void print_dnsfail(adns_status st, struct query_node *qun, adns_answer *a
   }
   assert(ov_format == fmt_simple);
   if (st == adns_s_nxdomain) {
   }
   assert(ov_format == fmt_simple);
   if (st == adns_s_nxdomain) {
-    r= fprintf(stderr,"%s does not exist\n", answer->owner);
+    r= fprintf(stderr,"%s does not exist\n", owner_show(qun,answer));
   } else {
     ist= adns_rr_info(answer->type, &typename, 0,0,0,0);
     if (st == adns_s_nodata) {
   } else {
     ist= adns_rr_info(answer->type, &typename, 0,0,0,0);
     if (st == adns_s_nodata) {
-      r= fprintf(stderr,"%s has no %s record\n", answer->owner, typename);
+      r= fprintf(stderr,"%s has no %s record\n", owner_show(qun,answer), typename);
     } else {
       statusstring= adns_strerror(st);
       r= fprintf(stderr,"Error during DNS %s lookup for %s: %s\n",
     } else {
       statusstring= adns_strerror(st);
       r= fprintf(stderr,"Error during DNS %s lookup for %s: %s\n",
-                typename, answer->owner, statusstring);
+                typename, owner_show(qun,answer), statusstring);
     }
   }
   if (r == EOF) sysfail("write error message to stderr",errno);
     }
   }
   if (r == EOF) sysfail("write error message to stderr",errno);
@@ -233,7 +239,7 @@ void query_done(struct query_node *qun, adns_answer *answer) {
     }
   }
   if (qun->pqfr.show_owner) {
     }
   }
   if (qun->pqfr.show_owner) {
-    realowner= answer->cname ? answer->cname : answer->owner;
+    realowner= answer->cname ? answer->cname : owner_show(qun,answer);
     assert(realowner);
   } else {
     realowner= 0;
     assert(realowner);
   } else {
     realowner= 0;
index 8b459b3..93a7608 100644 (file)
@@ -90,7 +90,7 @@ void opt_do(const struct optioninfo *oip, const char *arg, int invert);
 struct query_node {
   struct query_node *next, *back;
   struct perqueryflags_remember pqfr;
 struct query_node {
   struct query_node *next, *back;
   struct perqueryflags_remember pqfr;
-  char *id;
+  char *id, *owner;
   adns_query qu;
 };
 
   adns_query qu;
 };
 
index feb9f9d..6643864 100644 (file)
@@ -284,7 +284,7 @@ typedef struct {
 typedef struct {
   adns_status status;
   char *cname; /* always NULL if query was for CNAME records */
 typedef struct {
   adns_status status;
   char *cname; /* always NULL if query was for CNAME records */
-  char *owner; /* only set if requested in query flags */
+  char *owner; /* only set if requested in query flags, and may be 0 on error anyway */
   adns_rrtype type; /* guaranteed to be same as in query */
   time_t expires; /* expiry time, defined only if _s_ok, nxdomain or nodata. NOT TTL! */
   int nrrs, rrsz; /* nrrs is 0 if an error occurs */
   adns_rrtype type; /* guaranteed to be same as in query */
   time_t expires; /* expiry time, defined only if _s_ok, nxdomain or nodata. NOT TTL! */
   int nrrs, rrsz; /* nrrs is 0 if an error occurs */
index 8793762..d5bdcb0 100644 (file)
@@ -244,7 +244,7 @@ static const struct sinfo {
 
   SINFO(  querydomainwrong,    "Domain invalid for particular DNS query type"  ),
   SINFO(  querydomaininvalid,  "Domain name is syntactically invalid"          ),
 
   SINFO(  querydomainwrong,    "Domain invalid for particular DNS query type"  ),
   SINFO(  querydomaininvalid,  "Domain name is syntactically invalid"          ),
-  SINFO(  querydomaintoolong,  "Domain name is too long"                       ),
+  SINFO(  querydomaintoolong,  "Domain name or component is too long"          ),
 
   SINFO(  nxdomain,            "No such domain"                                ),
   SINFO(  nodata,              "No such data"                                  )
 
   SINFO(  nxdomain,            "No such domain"                                ),
   SINFO(  nodata,              "No such data"                                  )
index c669af6..b97ffc6 100644 (file)
@@ -77,7 +77,7 @@ static adns_status mkquery_footer(vbuf *vb, adns_rrtype type) {
 adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r,
                          const char *owner, int ol,
                          const typeinfo *typei, adns_queryflags flags) {
 adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r,
                          const char *owner, int ol,
                          const typeinfo *typei, adns_queryflags flags) {
-  int ll, c, nlabs;
+  int ll, c, nbytes;
   byte label[255], *rqp;
   const char *p, *pe;
   adns_status st;
   byte label[255], *rqp;
   const char *p, *pe;
   adns_status st;
@@ -87,7 +87,7 @@ adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r,
   MKQUERY_START(vb);
 
   p= owner; pe= owner+ol;
   MKQUERY_START(vb);
 
   p= owner; pe= owner+ol;
-  nlabs= 0;
+  nbytes= 0;
   while (p!=pe) {
     ll= 0;
     while (p!=pe && (c= *p++)!='.') {
   while (p!=pe) {
     ll= 0;
     while (p!=pe && (c= *p++)!='.') {
@@ -115,7 +115,9 @@ adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r,
       label[ll++]= c;
     }
     if (!ll) return adns_s_querydomaininvalid;
       label[ll++]= c;
     }
     if (!ll) return adns_s_querydomaininvalid;
-    if (nlabs++ > 63) return adns_s_querydomaintoolong;
+    if (ll > 63) return adns_s_querydomaintoolong;
+    nbytes+= ll+1;
+    if (nbytes > 254) return adns_s_querydomaintoolong;
     MKQUERY_ADDB(ll);
     memcpy(rqp,label,ll); rqp+= ll;
   }
     MKQUERY_ADDB(ll);
     memcpy(rqp,label,ll); rqp+= ll;
   }