chiark / gitweb /
Sends packet, is apparently OK (tcpdump shows response is OK).
authorian <ian>
Sun, 27 Sep 1998 23:57:12 +0000 (23:57 +0000)
committerian <ian>
Sun, 27 Sep 1998 23:57:12 +0000 (23:57 +0000)
src/adns-internal.h
src/adns.c
src/adns.h

index f4fe829c7368505f37dca783c11aaa9dc310b14c..f47fc966c7f9677a9821c587098cdb527227c92c 100644 (file)
@@ -25,17 +25,17 @@ struct adns__query {
   int querylen;
   char owner[1];
   /* Possible states:
-   *  Queue   child  answer   nextserver  sentudp             senttcp
-   *  input   null   null     0           all bits zero       all bits zero
-   *  timew   null   null     any         at least 1 bit set  any
-   *  childw  set    partial  any         any                 any
-   *  output  null   set      any         any                 any
+   *  Queue   child  id   answer    nextserver  sentudp             senttcp
+   *  tosend  null   >=0  null      any         any                 any
+   *  timew   null   >=0  null      any         at least 1 bit set  any
+   *  childw  set    >=0  partial   any         any                 any
+   *  output  null   -1   set/null  any         any                 any
    */
 };
 
 struct adns__state {
   adns_initflags iflags;
-  struct { adns_query head, tail; } input, timew, childw, output;
+  struct { adns_query head, tail; } tosend, timew, childw, output;
   int nextid, udpsocket;
   int qbufavail, tcpbufavail, tcpbufused, tcpbufdone;
   unsigned char *qbuf, *tcpbuf;
index c4330a8864dad4bd12bb14ab5dbab8aad4f46ca7..bde99e21a53852ab1120259fca56e6a13fcd8800 100644 (file)
@@ -218,7 +218,7 @@ int adns_init(adns_state *ads_r, adns_initflags flags) {
   int r;
   
   ads= malloc(sizeof(*ads)); if (!ads) return errno;
-  ads->input.head= ads->input.tail= 0;
+  ads->tosend.head= ads->tosend.tail= 0;
   ads->timew.head= ads->timew.tail= 0;
   ads->childw.head= ads->childw.tail= 0;
   ads->output.head= ads->output.tail= 0;
@@ -281,7 +281,8 @@ static void query_fail(adns_state ads, adns_query qu, adns_status stat) {
     ans->nrrs= 0;
   }
   qu->answer= ans;
-  LIST_LINK_TAIL(ads->input,qu);
+  qu->id= -1;
+  LIST_LINK_TAIL(ads->output,qu);
 }
 
 int adns_finish(adns_state ads) {
@@ -311,21 +312,34 @@ int adns_callback(adns_state ads, int maxfd,
 
 static int internal_check(adns_state ads,
                          adns_query *query_io,
-                         adns_answer *answer,
-                         void *context_r) {
-  abort(); /* FIXME */
+                         adns_answer **answer,
+                         void **context_r) {
+  adns_query qu;
+
+  qu= *query_io;
+  if (!qu) {
+    if (!ads->output.head) return EWOULDBLOCK;
+    qu= ads->output.head;
+  } else {
+    if (qu->id>=0) return EWOULDBLOCK;
+  }
+  LIST_UNLINK(ads->output,qu);
+  *answer= qu->answer;
+  if (context_r) *context_r= qu->context;
+  free(qu);
+  return 0;
 }
 
 int adns_wait(adns_state ads,
              adns_query *query_io,
-             adns_answer *answer,
-             void *context_r) {
+             adns_answer **answer_r,
+             void **context_r) {
   int r, maxfd, rsel, rcb;
   fd_set readfds, writefds, exceptfds;
   struct timeval tvbuf, *tvp;
   
   for (;;) {
-    r= internal_check(ads,query_io,answer,context_r);
+    r= internal_check(ads,query_io,answer_r,context_r);
     if (r && r != EWOULDBLOCK) return r;
     FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
     maxfd= 0; tvp= 0;
@@ -339,17 +353,17 @@ int adns_wait(adns_state ads,
 
 int adns_check(adns_state ads,
               adns_query *query_io,
-              adns_answer *answer,
-              void *context_r) {
+              adns_answer **answer_r,
+              void **context_r) {
   autosys(ads);
-  return internal_check(ads,query_io,answer,context_r);
+  return internal_check(ads,query_io,answer_r,context_r);
 }
 
 int adns_synchronous(adns_state ads,
                     const char *owner,
                     adns_rrtype type,
                     adns_queryflags flags,
-                    adns_answer *answer) {
+                    adns_answer **answer_r) {
   adns_query qu;
   int r;
   
@@ -357,7 +371,7 @@ int adns_synchronous(adns_state ads,
   if (r) return r;
 
   do {
-    r= adns_wait(ads,&qu,answer,0);
+    r= adns_wait(ads,&qu,answer_r,0);
   } while (r==EINTR);
   if (r) adns_cancel(ads,qu);
   return r;
@@ -465,6 +479,16 @@ static int failsubmit(adns_state ads, void *context, adns_query *query_r,
   return 0;
 }
 
+static void trysendudp(adns_state ads, adns_query qu) {
+  struct sockaddr_in servaddr;
+  /* FIXME: _f_usevc not implemented */
+  memset(&servaddr,0,sizeof(servaddr));
+  servaddr.sin_family= AF_INET;
+  servaddr.sin_addr= ads->servers[qu->nextserver].addr;
+  servaddr.sin_port= htons(53);
+  sendto(ads->udpsocket,qu->querymsg,qu->querylen,0,&servaddr,sizeof(servaddr));
+}
+
 int adns_submit(adns_state ads,
                const char *owner,
                adns_rrtype type,
@@ -487,7 +511,8 @@ int adns_submit(adns_state ads,
 
   qu= allocquery(ads,owner,ol,qml,id,type,flags,context); if (!qu) return errno;
 
-  LIST_LINK_TAIL(ads->input,qu);
+  LIST_LINK_TAIL(ads->tosend,qu);
+  trysendudp(ads,qu);
   autosys(ads);
 
   *query_r= qu;
index 70e743ba9a9649b6aa3017d72623aee479e1ba2e..87e94e65c3659d33e00f1ebf707c4ae85dfdb48b 100644 (file)
@@ -68,13 +68,14 @@ typedef enum {
   adns_s_max_tempfail= 99,
   adns_s_nxdomain,
   adns_s_norecord,
+  adns_s_inconsistent, /* for bad PTR */
   adns_s_invaliddomain
 } adns_status;
 
 /* In dereferenced answers, multiple addresses show up as multiple
- * answers with all the dm pointers being the same.  If no
- * address is available (permanent failure) then INADDR_NONE is
- * used.
+ * answers with all the dm pointers being the same, with ref= adns_s_ok.
+ * If no address is available then INADDR_NONE is used, and ref indicates
+ * the error.
  */
 
 typedef struct {
@@ -83,16 +84,19 @@ typedef struct {
   adns_rrtype type;
   int nrrs;
   union {
-    struct in_addr inaddr[1];                                          /* a */
-    char (*str)[1];                     /* ns_raw, cname, ptr, ptr_raw, txt */
-    struct { char *dm; struct in_addr addr; } dmaddr;                 /* ns */
-    struct { char *a, *b; } strpair[1];                /* hinfo, rp, rp_raw */
-    struct { int pref; char *dm; struct in_addr addr; } intdmaddr[1]; /* mx */
-    struct { int pref; char *str; } intstr[1]; /* mx_raw */
+    struct in_addr inaddr[1];                                                    /* a */
+    char (*str)[1];                               /* ns_raw, cname, ptr, ptr_raw, txt */
+    struct { char *dm; adns_status ref; struct in_addr addr; } dmaddr;          /* ns */
+    struct { char *a, *b; } strpair[1];                          /* hinfo, rp, rp_raw */
+    struct {
+      int pref; char *dm;
+      adns_status ref; struct in_addr addr;
+    } intdmaddr[1];                                                             /* mx */
+    struct { int pref; char *str; } intstr[1];                              /* mx_raw */
     struct {
       char *ns0, *rp;
       unsigned long serial, refresh, retry, expire, minimum;
-    } soa[1]; /* soa, soa_raw */
+    } soa[1];                                                         /* soa, soa_raw */
     /* NULL is empty */
   } rrs;
 } adns_answer;
@@ -125,7 +129,7 @@ int adns_synchronous(adns_state ads,
                     const char *owner,
                     adns_rrtype type,
                     adns_queryflags flags,
-                    adns_answer *answer);
+                    adns_answer **answer_r);
 /* Will not return EINTR. */
 
 /* NB: if you set adns_if_noautosys then _submit and _check do not
@@ -142,13 +146,13 @@ int adns_submit(adns_state ads,
 
 int adns_check(adns_state ads,
               adns_query *query_io,
-              adns_answer *answer,
-              void *context_r);
+              adns_answer **answer_r,
+              void **context_r);
 
 int adns_wait(adns_state ads,
              adns_query *query_io,
-             adns_answer *answer,
-             void *context_r);
+             adns_answer **answer_r,
+             void **context_r);
 /* Might return EINTR - if so, try again */
 
 void adns_cancel(adns_state ads, adns_query query);