chiark / gitweb /
Halfway through getting it to compile; about to move various bits of
authorian <ian>
Sun, 8 Nov 1998 14:39:01 +0000 (14:39 +0000)
committerian <ian>
Sun, 8 Nov 1998 14:39:01 +0000 (14:39 +0000)
code abo9ut.

src/event.c
src/internal.h
src/parse.c
src/query.c
src/setup.c
src/submit.c
src/types.c

index cd76707eff81f3cc1444c5dcd4427a8a299b0179..7a28e01b0cfd102927c6ec9337deb1ef07d925ba 100644 (file)
@@ -17,7 +17,7 @@ void adns__tcp_broken(adns_state ads, const char *what, const char *why) {
   
   assert(ads->tcpstate == server_connecting || ads->tcpstate == server_ok);
   serv= ads->tcpserver;
   
   assert(ads->tcpstate == server_connecting || ads->tcpstate == server_ok);
   serv= ads->tcpserver;
-  adns__warn(ads,serv,"TCP connection lost: %s: %s",what,why);
+  adns__warn(ads,serv,0,"TCP connection lost: %s: %s",what,why);
   close(ads->tcpsocket);
   ads->tcpstate= server_disconnected;
   
   close(ads->tcpsocket);
   ads->tcpstate= server_disconnected;
   
@@ -40,7 +40,7 @@ void adns__tcp_broken(adns_state ads, const char *what, const char *why) {
 static void tcp_connected(adns_state ads, struct timeval now) {
   adns_query qu, nqu;
   
 static void tcp_connected(adns_state ads, struct timeval now) {
   adns_query qu, nqu;
   
-  adns__debug(ads,ads->tcpserver,"TCP connected");
+  adns__debug(ads,ads->tcpserver,0,"TCP connected");
   ads->tcpstate= server_ok;
   for (qu= ads->timew.head; qu; qu= nqu) {
     nqu= qu->next;
   ads->tcpstate= server_ok;
   for (qu= ads->timew.head; qu; qu= nqu) {
     nqu= qu->next;
@@ -63,15 +63,15 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now) {
     assert(!ads->tcprecv.used);
 
     proto= getprotobyname("tcp");
     assert(!ads->tcprecv.used);
 
     proto= getprotobyname("tcp");
-    if (!proto) { adns__diag(ads,-1,"unable to find protocol no. for TCP !"); return; }
+    if (!proto) { adns__diag(ads,-1,0,"unable to find protocol no. for TCP !"); return; }
     fd= socket(AF_INET,SOCK_STREAM,proto->p_proto);
     if (fd<0) {
     fd= socket(AF_INET,SOCK_STREAM,proto->p_proto);
     if (fd<0) {
-      adns__diag(ads,-1,"cannot create TCP socket: %s",strerror(errno));
+      adns__diag(ads,-1,0,"cannot create TCP socket: %s",strerror(errno));
       return;
     }
     r= adns__setnonblock(ads,fd);
     if (r) {
       return;
     }
     r= adns__setnonblock(ads,fd);
     if (r) {
-      adns__diag(ads,-1,"cannot make TCP socket nonblocking: %s",strerror(r));
+      adns__diag(ads,-1,0,"cannot make TCP socket nonblocking: %s",strerror(r));
       close(fd);
       return;
     }
       close(fd);
       return;
     }
@@ -159,7 +159,8 @@ fprintf(stderr,"adns_interest\n");
 
 r= gettimeofday(&now,0);
   if (r) {
 
 r= gettimeofday(&now,0);
   if (r) {
-    adns__warn(ads,-1,"gettimeofday failed - will sleep for a bit: %s",strerror(errno));
+    adns__warn(ads,-1,0,"gettimeofday failed - will sleep for a bit: %s",
+              strerror(errno));
     timerclear(&tvto_lr); timevaladd(&tvto_lr,LOCALRESOURCEMS);
     inter_maxto(tv_io, tvbuf, tvto_lr);
   } else {
     timerclear(&tvto_lr); timevaladd(&tvto_lr,LOCALRESOURCEMS);
     inter_maxto(tv_io, tvbuf, tvto_lr);
   } else {
@@ -281,21 +282,21 @@ static int internal_callback(adns_state ads, int maxfd,
       if (r<0) {
        if (!(errno == EAGAIN || errno == EWOULDBLOCK ||
              errno == EINTR || errno == ENOMEM || errno == ENOBUFS))
       if (r<0) {
        if (!(errno == EAGAIN || errno == EWOULDBLOCK ||
              errno == EINTR || errno == ENOMEM || errno == ENOBUFS))
-         adns__warn(ads,-1,"datagram receive error: %s",strerror(errno));
+         adns__warn(ads,-1,0,"datagram receive error: %s",strerror(errno));
        break;
       }
       if (udpaddrlen != sizeof(udpaddr)) {
        break;
       }
       if (udpaddrlen != sizeof(udpaddr)) {
-       adns__diag(ads,-1,"datagram received with wrong address length %d (expected %d)",
-                  udpaddrlen,sizeof(udpaddr));
+       adns__diag(ads,-1,0,"datagram received with wrong address length %d"
+                  " (expected %d)", udpaddrlen,sizeof(udpaddr));
        continue;
       }
       if (udpaddr.sin_family != AF_INET) {
        continue;
       }
       if (udpaddr.sin_family != AF_INET) {
-       adns__diag(ads,-1,"datagram received with wrong protocol family"
+       adns__diag(ads,-1,0,"datagram received with wrong protocol family"
                   " %u (expected %u)",udpaddr.sin_family,AF_INET);
        continue;
       }
       if (ntohs(udpaddr.sin_port) != DNS_PORT) {
                   " %u (expected %u)",udpaddr.sin_family,AF_INET);
        continue;
       }
       if (ntohs(udpaddr.sin_port) != DNS_PORT) {
-       adns__diag(ads,-1,"datagram received from wrong port %u (expected %u)",
+       adns__diag(ads,-1,0,"datagram received from wrong port %u (expected %u)",
                   ntohs(udpaddr.sin_port),DNS_PORT);
        continue;
       }
                   ntohs(udpaddr.sin_port),DNS_PORT);
        continue;
       }
@@ -304,7 +305,7 @@ static int internal_callback(adns_state ads, int maxfd,
             ads->servers[serv].addr.s_addr != udpaddr.sin_addr.s_addr;
           serv++);
       if (serv >= ads->nservers) {
             ads->servers[serv].addr.s_addr != udpaddr.sin_addr.s_addr;
           serv++);
       if (serv >= ads->nservers) {
-       adns__warn(ads,-1,"datagram received from unknown nameserver %s",
+       adns__warn(ads,-1,0,"datagram received from unknown nameserver %s",
                   inet_ntoa(udpaddr.sin_addr));
        continue;
       }
                   inet_ntoa(udpaddr.sin_addr));
        continue;
       }
index b121c9f7e0f1cb22ef2d1b43e26e0200cb15e992..58d4a4c7c52c417bbad06db530a7a3b9031cc7b7 100644 (file)
@@ -60,6 +60,7 @@ typedef union {
 
 typedef struct {
   adns_rrtype type;
 
 typedef struct {
   adns_rrtype type;
+  const char *name;
   int rrsz;
 
   adns_status (*parse)(adns_state ads, adns_query qu, int serv,
   int rrsz;
 
   adns_status (*parse)(adns_state ads, adns_query qu, int serv,
@@ -99,7 +100,8 @@ struct adns__query {
   struct { adns_query head, tail; } children;
   struct { adns_query back, next; } siblings;
   struct allocnode *allocations;
   struct { adns_query head, tail; } children;
   struct { adns_query back, next; } siblings;
   struct allocnode *allocations;
-  int interim_alloced, final_used;
+  int interim_allocd;
+  void *final_allocspace;
   
   const typeinfo *typei;
   char *query_dgram;
   
   const typeinfo *typei;
   char *query_dgram;
@@ -199,14 +201,14 @@ struct adns__state {
 /* From setup.c: */
 
 void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
 /* From setup.c: */
 
 void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
-                int serv, const char *fmt, va_list al);
+                int serv, adns_query qu, const char *fmt, va_list al);
 
 void adns__debug(adns_state ads, int serv, adns_query qu,
 
 void adns__debug(adns_state ads, int serv, adns_query qu,
-                const char *fmt, ...) PRINTFFORMAT(3,4);
+                const char *fmt, ...) PRINTFFORMAT(4,5);
 void adns__warn(adns_state ads, int serv, adns_query qu,
 void adns__warn(adns_state ads, int serv, adns_query qu,
-               const char *fmt, ...) PRINTFFORMAT(3,4);
+               const char *fmt, ...) PRINTFFORMAT(4,5);
 void adns__diag(adns_state ads, int serv, adns_query qu,
 void adns__diag(adns_state ads, int serv, adns_query qu,
-               const char *fmt, ...) PRINTFFORMAT(3,4);
+               const char *fmt, ...) PRINTFFORMAT(4,5);
 
 int adns__vbuf_ensure(vbuf *vb, int want);
 int adns__vbuf_appendstr(vbuf *vb, const char *data);
 
 int adns__vbuf_ensure(vbuf *vb, int want);
 int adns__vbuf_appendstr(vbuf *vb, const char *data);
@@ -221,15 +223,16 @@ int adns__setnonblock(adns_state ads, int fd); /* => errno value */
 /* From submit.c: */
 
 int adns__internal_submit(adns_state ads, adns_query *query_r,
 /* From submit.c: */
 
 int adns__internal_submit(adns_state ads, adns_query *query_r,
-                         adns_rrtype type, char *query_dgram, int query_len,
+                         adns_rrtype type, vbuf *qumsg_vb, int id,
                          adns_queryflags flags, struct timeval now,
                          adns_status failstat, const qcontext *ctx);
 /* Submits a query (for internal use, called during external submits).
  *
  * The new query is returned in *query_r, or we return adns_s_nomemory.
  *
                          adns_queryflags flags, struct timeval now,
                          adns_status failstat, const qcontext *ctx);
 /* Submits a query (for internal use, called during external submits).
  *
  * The new query is returned in *query_r, or we return adns_s_nomemory.
  *
- * The query datagram should already have been assembled; memory for it
- * is taken over by this routine whether it succeeds or fails.
+ * The query datagram should already have been assembled in qumsg_vb;
+ * the memory for it is _taken over_ by this routine whether it
+ * succeeds or fails (if it succeeds, the vbuf is reused for qu->vb).
  *
  * If failstat is nonzero then if we are successful in creating the query
  * it is immediately failed with code failstat (but _submit still succeds).
  *
  * If failstat is nonzero then if we are successful in creating the query
  * it is immediately failed with code failstat (but _submit still succeds).
@@ -255,16 +258,29 @@ void *adns__alloc_final(adns_query qu, size_t sz);
 /* Cannot fail.
  */
 
 /* Cannot fail.
  */
 
+void adns__makefinal_block(adns_query qu, void **blpp, size_t sz);
+void adns__makefinal_str(adns_query qu, char **strp);
+
 /* From query.c: */
 
 void adns__query_udp(adns_state ads, adns_query qu, struct timeval now);
 void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now);
 /* From query.c: */
 
 void adns__query_udp(adns_state ads, adns_query qu, struct timeval now);
 void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now);
-adns_status adns__mkquery(adns_state ads, const char *owner, int ol, int id,
+adns_status adns__mkquery(adns_state ads, vbuf *vb,
+                         const char *owner, int ol, int *id_r,
                          const typeinfo *typei, adns_queryflags flags);
                          const typeinfo *typei, adns_queryflags flags);
+/* Assembles a query packet in vb, and returns id at *id_r. */
 
 void adns__query_ok(adns_state ads, adns_query qu);
 void adns__query_fail(adns_state ads, adns_query qu, adns_status stat);
 
 
 void adns__query_ok(adns_state ads, adns_query qu);
 void adns__query_fail(adns_state ads, adns_query qu, adns_status stat);
 
+void adns__reset_cnameonly(adns_state ads, adns_query qu);
+/* Resets all of the memory management stuff etc. to
+ * take account of only the CNAME.  Used when we find an error somewhere
+ * and want to just report the error (with perhaps CNAME info), and also
+ * when we're halfway through RRs in a datagram and discover that we
+ * need to retry the query.
+ */
+   
 /* From reply.c: */
 
 void adns__procdgram(adns_state ads, const byte *dgram, int len,
 /* From reply.c: */
 
 void adns__procdgram(adns_state ads, const byte *dgram, int len,
@@ -277,7 +293,8 @@ const typeinfo *adns__findtype(adns_rrtype type);
 /* From parse.c: */
 
 typedef struct {
 /* From parse.c: */
 
 typedef struct {
-  adns_state ads, int serv;
+  adns_state ads;
+  int serv;
   const byte *dgram;
   int dglen, max, cbyte, namelen;
   int *dmend_rlater, *namelen_rlater;
   const byte *dgram;
   int dglen, max, cbyte, namelen;
   int *dmend_rlater, *namelen_rlater;
index 957b57232994121321d1daab9632d889d9b5e906..9691dccaa1ed789e66ea6a59f956658b683bf51c 100644 (file)
@@ -54,7 +54,7 @@ adns_status adns__findlabel_next(findlabel_state fls,
     if (!(lablen & 0x0c000)) break;
     if ((lablen & 0x0c000) != 0x0c000) return adns_s_unknownreply;
     if (jumped++) {
     if (!(lablen & 0x0c000)) break;
     if ((lablen & 0x0c000) != 0x0c000) return adns_s_unknownreply;
     if (jumped++) {
-      adns__diag(ads,serv,"compressed datagram contains loop");
+      adns__diag(ads,fls->serv,fls->qu,"compressed datagram contains loop");
       return adns_s_serverfaulty;
     }
     if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte;
       return adns_s_serverfaulty;
     }
     if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte;
@@ -81,7 +81,7 @@ adns_status adns__findlabel_next(findlabel_state fls,
   return adns_s_ok;
 
  x_serverfaulty: 
   return adns_s_ok;
 
  x_serverfaulty: 
-  adns__diag(ads,serv,"label in domain runs beyond end of domain");
+  adns__diag(ads,fls->serv,fls->qu,"label in domain runs beyond end of domain");
   return adns_s_serverfaulty;
 }
 
   return adns_s_serverfaulty;
 }
 
@@ -120,17 +120,22 @@ adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, int flags,
   return adns_s_ok;
 }
        
   return adns_s_ok;
 }
        
-const char *adns__diag_domain(adns_state ads, int serv, vbuf *vb, int flags,
-                             const byte *dgram, int dglen, int cbyte) {
+const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb,
+                             int flags, const byte *dgram, int dglen, int cbyte) {
   adns_status st;
 
   st= adns__parse_domain(ads,serv,vb,qu->flags, dgram,dglen, &cbyte,dglen);
   adns_status st;
 
   st= adns__parse_domain(ads,serv,vb,qu->flags, dgram,dglen, &cbyte,dglen);
+  if (st == adns_s_nomemory) {
+    return "<cannot report domain... out of memory>";
+  }
   if (st) {
     vb->used= 0;
   if (st) {
     vb->used= 0;
-    adns__vbuf_appendstr(vb,"<bad format... ");
-    adns__vbuf_appendstr(vb,adns_strerror(st));
-    adns__vbuf_appendstr(vb,">");
-    adns__vbuf_append(vb,"",1);
+    if (!(adns__vbuf_appendstr(vb,"<bad format... ") &&
+         adns__vbuf_appendstr(vb,adns_strerror(st)) &&
+         adns__vbuf_appendstr(vb,">") &&
+         adns__vbuf_append(vb,"",1))) {
+      return "<cannot report bad format... out of memory>";
+    }
   }
   if (!vb.used) {
     adns__vbuf_appendstr(vb,"<truncated ...>");
   }
   if (!vb.used) {
     adns__vbuf_appendstr(vb,"<truncated ...>");
index ddd506454d48b481eb1559bedd1e44448950b31f..890757ec692fa3d20eedcce75f2088935cc9d4ed 100644 (file)
@@ -8,19 +8,22 @@
 
 #include "internal.h"
 
 
 #include "internal.h"
 
-adns_status adns__mkquery(adns_state ads, const char *owner, int ol, int id,
+adns_status adns__mkquery(adns_state ads, vbuf *vb,
+                         const char *owner, int ol, int *id_r,
                          const typeinfo *typei, adns_queryflags flags) {
                          const typeinfo *typei, adns_queryflags flags) {
-  /* Assembles a query packet in ads->rqbuf. */
-  int ll, c, nlabs;
+  int ll, c, nlabs, id;
   byte label[255], *rqp;
   const char *p, *pe;
 
 #define MKQUERY_ADDB(b) *rqp++= (b)
 #define MKQUERY_ADDW(w) (MKQUERY_ADDB(((w)>>8)&0x0ff), MKQUERY_ADDB((w)&0x0ff))
 
   byte label[255], *rqp;
   const char *p, *pe;
 
 #define MKQUERY_ADDB(b) *rqp++= (b)
 #define MKQUERY_ADDW(w) (MKQUERY_ADDB(((w)>>8)&0x0ff), MKQUERY_ADDB((w)&0x0ff))
 
-  if (!adns__vbuf_ensure(&ads->rqbuf,DNS_HDRSIZE+strlen(owner)+1+5))
+  vb->used= 0;
+  if (!adns__vbuf_ensure(vb,DNS_HDRSIZE+strlen(owner)+1+5))
     return adns_s_nolocalmem;
     return adns_s_nolocalmem;
-  rqp= ads->rqbuf.buf;
+  rqp= vb->buf;
+
+  *id_r= id= (ads->nextid++) & 0x0ffff;
 
   MKQUERY_ADDW(id);
   MKQUERY_ADDB(0x01); /* QR=Q(0), OPCODE=QUERY(0000), !AA, !TC, RD */
 
   MKQUERY_ADDW(id);
   MKQUERY_ADDB(0x01); /* QR=Q(0), OPCODE=QUERY(0000), !AA, !TC, RD */
@@ -68,8 +71,8 @@ adns_status adns__mkquery(adns_state ads, const char *owner, int ol, int id,
   MKQUERY_ADDW(typei->type & adns__rrt_typemask); /* QTYPE */
   MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */
 
   MKQUERY_ADDW(typei->type & adns__rrt_typemask); /* QTYPE */
   MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */
 
-  ads->rqbuf.used= rqp - ads->rqbuf.buf;
-  assert(ads->rqbuf.used <= ads->rqbuf.avail);
+  vb->used= rqp - vb->buf;
+  assert(vb->used <= vb->avail);
   
   return adns_s_ok;
 }
   
   return adns_s_ok;
 }
@@ -91,10 +94,10 @@ void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) {
 
   if (ads->tcpstate != server_ok) return;
 
 
   if (ads->tcpstate != server_ok) return;
 
-  length[0]= (qu->querylen&0x0ff00U) >>8;
-  length[1]= (qu->querylen&0x0ff);
+  length[0]= (qu->query_dglen&0x0ff00U) >>8;
+  length[1]= (qu->query_dglen&0x0ff);
   
   
-  if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->querylen+2)) return;
+  if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->query_dglen+2)) return;
 
   timevaladd(&now,TCPMS);
   qu->timeout= now;
 
   timevaladd(&now,TCPMS);
   qu->timeout= now;
@@ -106,8 +109,8 @@ void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) {
   } else {
     iov[0].iov_base= length;
     iov[0].iov_len= 2;
   } else {
     iov[0].iov_base= length;
     iov[0].iov_len= 2;
-    iov[1].iov_base= qu->querymsg;
-    iov[1].iov_len= qu->querylen;
+    iov[1].iov_base= qu->query_dgram;
+    iov[1].iov_len= qu->query_dglen;
     wr= writev(ads->tcpsocket,iov,2);
     if (wr < 0) {
       if (!(errno == EAGAIN || errno == EINTR || errno == ENOSPC ||
     wr= writev(ads->tcpsocket,iov,2);
     if (wr < 0) {
       if (!(errno == EAGAIN || errno == EINTR || errno == ENOSPC ||
@@ -125,8 +128,8 @@ void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) {
   } else {
     wr-= 2;
   }
   } else {
     wr-= 2;
   }
-  if (wr<qu->querylen) {
-    r= adns__vbuf_append(&ads->tcpsend,qu->querymsg+wr,qu->querylen-wr); assert(r);
+  if (wr<qu->query_dglen) {
+    r= adns__vbuf_append(&ads->tcpsend,qu->query_dgram+wr,qu->query_dglen-wr); assert(r);
   }
 }
 
   }
 }
 
@@ -149,7 +152,7 @@ void adns__query_udp(adns_state ads, adns_query qu, struct timeval now) {
   int serv, r;
 
   assert(qu->state == query_udp);
   int serv, r;
 
   assert(qu->state == query_udp);
-  if ((qu->flags & adns_qf_usevc) || (qu->querylen > DNS_MAXUDP)) {
+  if ((qu->flags & adns_qf_usevc) || (qu->query_dglen > DNS_MAXUDP)) {
     query_usetcp(ads,qu,now);
     return;
   }
     query_usetcp(ads,qu,now);
     return;
   }
@@ -165,9 +168,9 @@ void adns__query_udp(adns_state ads, adns_query qu, struct timeval now) {
   servaddr.sin_addr= ads->servers[serv].addr;
   servaddr.sin_port= htons(DNS_PORT);
   
   servaddr.sin_addr= ads->servers[serv].addr;
   servaddr.sin_port= htons(DNS_PORT);
   
-  r= sendto(ads->udpsocket,qu->querymsg,qu->querylen,0,&servaddr,sizeof(servaddr));
+  r= sendto(ads->udpsocket,qu->query_dgram,qu->query_dglen,0,&servaddr,sizeof(servaddr));
   if (r<0 && errno == EMSGSIZE) { query_usetcp(ads,qu,now); return; }
   if (r<0 && errno == EMSGSIZE) { query_usetcp(ads,qu,now); return; }
-  if (r<0) adns__warn(ads,serv,"sendto failed: %s",strerror(errno));
+  if (r<0) adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno));
   
   timevaladd(&now,UDPRETRYMS);
   qu->timeout= now;
   
   timevaladd(&now,UDPRETRYMS);
   qu->timeout= now;
@@ -180,11 +183,12 @@ void adns__query_udp(adns_state ads, adns_query qu, struct timeval now) {
 static void adns__query_done(adns_state ads, adns_query qu) {
   adns_answer *ans;
   allocnode *an, *ann;
 static void adns__query_done(adns_state ads, adns_query qu) {
   adns_answer *ans;
   allocnode *an, *ann;
+  int i;
 
   qu->answer= ans= realloc(qu->answer,
                           MEM_ROUND(MEM_ROUND(sizeof(*ans)) +
                                     qu->interim_allocd));
 
   qu->answer= ans= realloc(qu->answer,
                           MEM_ROUND(MEM_ROUND(sizeof(*ans)) +
                                     qu->interim_allocd));
-  qu->final_used= MEM_ROUND(sizeof(*ans));
+  qu->final_allocspace= (byte*)qu->answer + MEM_ROUND(sizeof(*ans));
 
   adns__makefinal_str(qu,&ans->cname);
   if (ans->nrrs) {
 
   adns__makefinal_str(qu,&ans->cname);
   if (ans->nrrs) {
@@ -202,14 +206,14 @@ static void adns__query_done(adns_state ads, adns_query qu) {
 }
 
 void adns__reset_cnameonly(adns_state ads, adns_query qu) {
 }
 
 void adns__reset_cnameonly(adns_state ads, adns_query qu) {
+  assert(qu->final_allocspace);
   qu->answer->nrrs= 0;
   qu->answer->rrs= 0;
   qu->answer->nrrs= 0;
   qu->answer->rrs= 0;
-  qu->permalloclen= qu->answer->cname ? MEM_ROUND(strlen(qu->answer->cname)+1) : 0;
+  qu->interim_allocd= qu->answer->cname ? MEM_ROUND(strlen(qu->answer->cname)+1) : 0;
 }
 
 void adns__query_fail(adns_state ads, adns_query qu, adns_status stat) {
   adns__reset_cnameonly(ads,qu);
   qu->answer->status= stat;
 }
 
 void adns__query_fail(adns_state ads, adns_query qu, adns_status stat) {
   adns__reset_cnameonly(ads,qu);
   qu->answer->status= stat;
-  qu->answer->type= qu->type;
-  adns__query_done(ads,qu,stat);
+  adns__query_done(ads,qu);
 }
 }
index 63469d264c28246920f3636c6bc0d39e8ffb3d0c..7ea538905149537759aea792444c699541375652 100644 (file)
 #include "internal.h"
 
 void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
 #include "internal.h"
 
 void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
-                int serv, const char *fmt, va_list al) {
+                int serv, const char *fmt, adns_query qu, va_list al) {
+  const char *bef, *aft;
+  vbuf vb;
   if (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent))) return;
   if (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent))) return;
+
+  fprintf(stderr,"adns%s: ",pfx);
+
+  vfprintf(stderr,fmt,al);
+
+  bef= " (";
+  aft= "\n";
+
+  if (qu && qu->query_dgram) {
+    adns__vbuf_init(&vb);
+    fprintf(stderr,"%sQNAME=%s, QTYPE=%s",
+           bef,
+           adns__diag_domain(ads,-1,0,&vb,qu->query_dgram,qu->query_dglen,DNS_HDRSIZE),
+           qu->typei ? qu->typei->name : "<unknown>");
+    bef=", "; aft=")\n";
+  }
+  
   if (serv>=0) {
   if (serv>=0) {
-    fprintf(stderr,"adns%s: nameserver %s: ",pfx,inet_ntoa(ads->servers[serv].addr));
-  } else {
-    fprintf(stderr,"adns%s: ",pfx);
+    fprintf(stderr,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr));
+    bef=", "; aft=")\n";
   }
   }
-  vfprintf(stderr,fmt,al);
-  fputc('\n',stderr);
+
+  fputs(aft,stderr);
 }
 
 }
 
-void adns__debug(adns_state ads, int serv, const char *fmt, ...) {
+void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
   va_list al;
 
   va_start(al,fmt);
   va_list al;
 
   va_start(al,fmt);
-  adns__vdiag(ads," debug",0,serv,fmt,al);
+  adns__vdiag(ads," debug",0,serv,qu,fmt,al);
   va_end(al);
 }
 
   va_end(al);
 }
 
-void adns__warn(adns_state ads, int serv, const char *fmt, ...) {
+void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
   va_list al;
 
   va_start(al,fmt);
   va_list al;
 
   va_start(al,fmt);
-  adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,fmt,al);
+  adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al);
   va_end(al);
 }
 
   va_end(al);
 }
 
-void adns__diag(adns_state ads, int serv, const char *fmt, ...) {
+void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
   va_list al;
 
   va_start(al,fmt);
   va_list al;
 
   va_start(al,fmt);
-  adns__vdiag(ads,"",adns_if_noerrprint,serv,fmt,al);
+  adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al);
   va_end(al);
 }
 
   va_end(al);
 }
 
index ee73b37516d92401695f5c0a6328dba36cfc03e9..197381d8c5bec6f89495c4aebb84ee2ed56de703 100644 (file)
@@ -9,21 +9,9 @@
 #include "internal.h"
 
 int adns__internal_submit(adns_state ads, adns_query *query_r,
 #include "internal.h"
 
 int adns__internal_submit(adns_state ads, adns_query *query_r,
-                         adns_rrtype type, char *query_dgram, int query_len,
+                         adns_rrtype type, vbuf *qumsg_vb, int id,
                          adns_queryflags flags, struct timeval now,
                          adns_status failstat, const qcontext *ctx) {
                          adns_queryflags flags, struct timeval now,
                          adns_status failstat, const qcontext *ctx) {
-  /* Submits a query (for internal use, called during external submits).
-   *
-   * The new query is returned in *query_r, or we return adns_s_nomemory.
-   *
-   * The query datagram should already have been assembled; memory for it
-   * is taken over by this routine whether it succeeds or fails.
-   *
-   * If failstat is nonzero then if we are successful in creating the query
-   * it is immediately failed with code failstat (but _submit still succeds).
-   *
-   * ctx is copied byte-for-byte into the query.
-   */
   adns_query qu;
   adns_status stat;
   int ol, id, r;
   adns_query qu;
   adns_status stat;
   int ol, id, r;
@@ -31,8 +19,6 @@ int adns__internal_submit(adns_state ads, adns_query *query_r,
   const typeinfo *typei;
   adns_query qu;
 
   const typeinfo *typei;
   adns_query qu;
 
-  id= ads->nextid++;
-
   qu= malloc(sizeof(*qu)); if (!qu) goto x_nomemory;
   qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) goto x_freequ_nomemory;
 
   qu= malloc(sizeof(*qu)); if (!qu) goto x_nomemory;
   qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) goto x_freequ_nomemory;
 
@@ -45,8 +31,6 @@ int adns__internal_submit(adns_state ads, adns_query *query_r,
   qu->perm_used= 0;
 
   qu->typei= adns__findtype(type);
   qu->perm_used= 0;
 
   qu->typei= adns__findtype(type);
-  qu->query_dgram= query_dgram;
-  qu->query_dglen= query_dglen;
   adns__vbuf_init(&qu->vb);
 
   qu->cname_dgram= 0;
   adns__vbuf_init(&qu->vb);
 
   qu->cname_dgram= 0;
@@ -67,19 +51,28 @@ int adns__internal_submit(adns_state ads, adns_query *query_r,
   qu->answer->nrrs= 0;
   qu->answer->rrs= 0;
 
   qu->answer->nrrs= 0;
   qu->answer->rrs= 0;
 
-  *query_r= qu;
-
   if (qu->typei) {
     qu->answer->rrsz= qu->rrsz;
   } else {
     qu->answer->rrsz= -1;
     failstat= adns_s_notimplemented;
   }
   if (qu->typei) {
     qu->answer->rrsz= qu->rrsz;
   } else {
     qu->answer->rrsz= -1;
     failstat= adns_s_notimplemented;
   }
+  
+  *query_r= qu;
+
+  qu->query_dgram= malloc(qumsg_vb->used);
+  if (!qu->query_dgram) {
+    adns__query_fail(ads,qu,adns_s_nomemory);
+    return;
+  }
+  memcpy(qu->query_dgram,qumsg_vb->buf,qumsg_vb->used);
+  qu->vb= *qumsg_vb;
+  adns__vbuf_init(qumsg_vb);
+  
   if (failstat) {
     adns__query_fail(ads,qu,failstat);
     return;
   }
   if (failstat) {
     adns__query_fail(ads,qu,failstat);
     return;
   }
-
   adns__query_udp(ads,qu,now);
   adns__autosys(ads,now);
 
   adns__query_udp(ads,qu,now);
   adns__autosys(ads,now);
 
@@ -99,19 +92,24 @@ int adns_submit(adns_state ads,
                void *context,
                adns_query *query_r) {
   qcontext ctx;
                void *context,
                adns_query *query_r) {
   qcontext ctx;
+  int id;
+  vbuf vb;
 
   ctx.ext= context;
   r= gettimeofday(&now,0); if (r) return errno;
 
   ctx.ext= context;
   r= gettimeofday(&now,0); if (r) return errno;
+  id= 0;
+
+  adns__vbuf_init(&vb);
 
   ol= strlen(owner);
 
   ol= strlen(owner);
-  if (ol<=1 || ol>DNS_MAXDOMAIN+1)
-    return failsubmit(ads,context,query_r,flags,id,adns_s_invaliddomain);
+  if (ol<=1 || ol>DNS_MAXDOMAIN+1) { stat= adns_s_invaliddomain; goto xit; }
+                                
   if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; }
 
   if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; }
 
-  stat= adns__mkquery(ads,owner,ol,id,typei,flags);
-  if (stat) return failsubmit(ads,context,query_r,flags,id,stat);
-  
-  adns__internal_submit(ads,type,flags,now,query_r
+  stat= adns__mkquery(ads,&vb, &id, owner,ol, typei,flags);
+                       
+ xit:
+  return adns__internal_submit(ads,query_r, type,&vb,id, flags,now, stat,&ctx);        
 }
 
 int adns_synchronous(adns_state ads,
 }
 
 int adns_synchronous(adns_state ads,
@@ -136,9 +134,29 @@ void adns_cancel(adns_state ads, adns_query query) {
   abort(); /* fixme */
 }
 
   abort(); /* fixme */
 }
 
+void adns__makefinal_str(adns_query qu, char **strp) {
+  int l;
+  char *before, *after;
+
+  before= *strp;
+  l= strlen(before)+1;
+  after= adns__alloc_final(qu,l);
+  memcpy(after,before,l);
+  *strp= after;  
+}
+
+void adns__makefinal_block(adns__query qu, void **blpp, size_t sz) {
+  void *after;
+
+  after= adns__alloc_final(qu,sz);
+  memcpy(after,*blpp,sz);
+  *blpp= after;
+}
+
 void *adns__alloc_interim(adns_state ads, adns_query qu, size_t sz) {
   allocnode *an;
 
 void *adns__alloc_interim(adns_state ads, adns_query qu, size_t sz) {
   allocnode *an;
 
+  assert(!qu->final_allocspace);
   sz= MEM_ROUND(sz);
   an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz));
   if (!an) {
   sz= MEM_ROUND(sz);
   an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz));
   if (!an) {
@@ -150,3 +168,19 @@ void *adns__alloc_interim(adns_state ads, adns_query qu, size_t sz) {
   qu->allocations= an;
   return (byte*)an + MEM_ROUND(sizeof(*an));
 }
   qu->allocations= an;
   return (byte*)an + MEM_ROUND(sizeof(*an));
 }
+
+void *adns__alloc_final(adns_query qu, size_t sz) {
+  /* When we're in the _final stage, we _subtract_ from interim_alloc'd
+   * each allocation, and use final_allocspace to point to the next free
+   * bit.
+   */
+  void *rp;
+
+  sz= MEM_ROUND(sz);
+  rp= qu->final_allocspace;
+  assert(rp);
+  qu->interim_allocd -= sz;
+  assert(qu->interim_allocd>=0);
+  qu->final_allocspace= (byte*)rp + sz;
+  return rp;
+}
index b2b140d64195d2842a1d8960f8dd8d3384a9d705..38330cf11a45e9dd04c27901beb8ab66e2e0a126 100644 (file)
@@ -29,26 +29,26 @@ static adns_status rmf_null(adns_state ads, adns_query qu, void *data) { }
 
 static const typeinfo typeinfos[] = {
   /* Must be in ascending order of rrtype ! */
 
 static const typeinfo typeinfos[] = {
   /* Must be in ascending order of rrtype ! */
-  /* rr type code     style     member     size  parser */
+  /* rr type code     name             style     member     size  parser */
   
   
-  {  adns_r_a,        TYPE_MN(  inaddr,          inaddr       ) },
-#if 0 /*fixme*/                                               
-  {  adns_r_ns_raw,   TYPE_MF(  str,             domain_raw   ) },
-  {  adns_r_cname,    TYPE_MF(  str,             domain_raw   ) },
-  {  adns_r_soa_raw,  TYPE_MF(  soa,             soa          ) },
-  {  adns_r_null,     TYPE_SN(              0,   null         ) },
-  {  adns_r_ptr_raw,  TYPE_MF(  str,             domain_raw   ) },
-  {  adns_r_hinfo,    TYPE_MF(  strpair,         hinfo        ) },
-  {  adns_r_mx_raw,   TYPE_MF(  intstr,          mx_raw       ) },
-  {  adns_r_txt,      TYPE_MF(  str,             txt          ) },
-  {  adns_r_rp_raw,   TYPE_MF(  strpair,         rp           ) },
-                                                                
-  {  adns_r_ns,       TYPE_MF(  dmaddr,          dmaddr       ) },
-  {  adns_r_ptr,      TYPE_MF(  str,             ptr          ) },
-  {  adns_r_mx,       TYPE_MF(  intdmaddr,       mx           ) },
-                                                                
-  {  adns_r_soa,      TYPE_MF(  soa,             soa          ) },
-  {  adns_r_rp,       TYPE_MF(  strpair,         rp           ) },
+  {  adns_r_a,        "A",             TYPE_MN(  inaddr,          inaddr       ) },
+#if 0 /*fixme*/                                               
+  {  adns_r_ns_raw,   "NS(raw)",       TYPE_MF(  str,             domain_raw   ) },
+  {  adns_r_cname,    "CNAME",         TYPE_MF(  str,             domain_raw   ) },
+  {  adns_r_soa_raw,  "SOA(raw)",      TYPE_MF(  soa,             soa          ) },
+  {  adns_r_null,     "NULL",          TYPE_SN(              0,   null         ) },
+  {  adns_r_ptr_raw,  "PTR(raw)",      TYPE_MF(  str,             domain_raw   ) },
+  {  adns_r_hinfo,    "HINFO",         TYPE_MF(  strpair,         hinfo        ) },
+  {  adns_r_mx_raw,   "MX(raw)",       TYPE_MF(  intstr,          mx_raw       ) },
+  {  adns_r_txt,      "TXT",           TYPE_MF(  str,             txt          ) },
+  {  adns_r_rp_raw,   "RP(raw)",       TYPE_MF(  strpair,         rp           ) },
+                                                             
+  {  adns_r_ns,       "NS(+addr)",     TYPE_MF(  dmaddr,          dmaddr       ) },
+  {  adns_r_ptr,      "PTR(checked)",  TYPE_MF(  str,             ptr          ) },
+  {  adns_r_mx,       "MX(+addr)",     TYPE_MF(  intdmaddr,       mx           ) },
+                                                             
+  {  adns_r_soa,      "SOA(822)",      TYPE_MF(  soa,             soa          ) },
+  {  adns_r_rp,       "RP(822)",       TYPE_MF(  strpair,         rp           ) },
 #endif
 };
 
 #endif
 };