chiark / gitweb /
Rearrangement more or less sorted, back to trying to get it to compile.
authorian <ian>
Sun, 8 Nov 1998 15:13:15 +0000 (15:13 +0000)
committerian <ian>
Sun, 8 Nov 1998 15:13:15 +0000 (15:13 +0000)
15 files changed:
client/adnstest.c
regress/junk [new file with mode: 0644]
src/Makefile
src/Makefile.in
src/adns.h
src/event.c
src/general.c [new file with mode: 0644]
src/internal.h
src/parse.c
src/query.c
src/reply.c
src/setup.c
src/submit.c [deleted file]
src/transmit.c [new file with mode: 0644]
src/types.c

index 2f9e525132f4df1b3d886e8456c3c9ce927f0ba7..94037b271249142591bda766255204cd6ff32d4e 100644 (file)
@@ -1,4 +1,24 @@
-/**/
+/*
+ * dtest.c
+ * - simple test program, not part of the library
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #include <stdio.h>
 #include <unistd.h>
 
 #include <stdio.h>
 #include <unistd.h>
diff --git a/regress/junk b/regress/junk
new file mode 100644 (file)
index 0000000..7992f49
--- /dev/null
@@ -0,0 +1,6 @@
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/uio.h>
index 2719f336e302d212b8c0c0ed14f350bff5561c8a..4096d8466aa4a8618e1dd9cd49817aa56dd02705 100644 (file)
@@ -1,3 +1,19 @@
+#  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+#  
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2, or (at your option)
+#  any later version.
+#  
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#  
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+
 CC=gcc $(WARNS) $(WERROR) $(OPTIMISE) $(DEBUG)
 DEBUG=-g
 OPTIMISE=-O2
 CC=gcc $(WARNS) $(WERROR) $(OPTIMISE) $(DEBUG)
 DEBUG=-g
 OPTIMISE=-O2
@@ -5,14 +21,15 @@ WARNS=       -Wall -Wmissing-prototypes -Wwrite-strings -Wstrict-prototypes \
        -Wcast-qual -Wpointer-arith
 WERROR=-Werror
 
        -Wcast-qual -Wpointer-arith
 WERROR=-Werror
 
+LIBOBJS=       event.o query.o setup.o transmit.o general.o reply.o parse.o
+ALLOBJS=       $(LIBOBJS) dtest.o
+
 all:           dtest
 
 all:           dtest
 
-dtest:         dtest.o event.o query.o setup.o submit.o reply.o parse.o
+dtest:         $(ALLOBJS)
 
 clean:
                rm -f dtest *.o
 
 
 clean:
                rm -f dtest *.o
 
-dtest.o:                                               adns.h
-
-event.o query.o setup.o submit.o reply.o parse.o:      internal.h adns.h
-
+dtest.o:       adns.h
+$(LIBOBJS):    adns.h internal.h
index 2719f336e302d212b8c0c0ed14f350bff5561c8a..4096d8466aa4a8618e1dd9cd49817aa56dd02705 100644 (file)
@@ -1,3 +1,19 @@
+#  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+#  
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2, or (at your option)
+#  any later version.
+#  
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#  
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+
 CC=gcc $(WARNS) $(WERROR) $(OPTIMISE) $(DEBUG)
 DEBUG=-g
 OPTIMISE=-O2
 CC=gcc $(WARNS) $(WERROR) $(OPTIMISE) $(DEBUG)
 DEBUG=-g
 OPTIMISE=-O2
@@ -5,14 +21,15 @@ WARNS=       -Wall -Wmissing-prototypes -Wwrite-strings -Wstrict-prototypes \
        -Wcast-qual -Wpointer-arith
 WERROR=-Werror
 
        -Wcast-qual -Wpointer-arith
 WERROR=-Werror
 
+LIBOBJS=       event.o query.o setup.o transmit.o general.o reply.o parse.o
+ALLOBJS=       $(LIBOBJS) dtest.o
+
 all:           dtest
 
 all:           dtest
 
-dtest:         dtest.o event.o query.o setup.o submit.o reply.o parse.o
+dtest:         $(ALLOBJS)
 
 clean:
                rm -f dtest *.o
 
 
 clean:
                rm -f dtest *.o
 
-dtest.o:                                               adns.h
-
-event.o query.o setup.o submit.o reply.o parse.o:      internal.h adns.h
-
+dtest.o:       adns.h
+$(LIBOBJS):    adns.h internal.h
index 29cf8157593fe16ea9186352cd5db613d86e8012..72683814d2c1870102a7bddf24171827fb2609f6 100644 (file)
@@ -4,6 +4,23 @@
  *
  * $Id$
  */
  *
  * $Id$
  */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #ifndef ADNS_H_INCLUDED
 #define ADNS_H_INCLUDED
 
 #ifndef ADNS_H_INCLUDED
 #define ADNS_H_INCLUDED
@@ -220,6 +237,9 @@ int adns_wait(adns_state ads,
 void adns_cancel(adns_state ads, adns_query query);
 
 int adns_finish(adns_state);
 void adns_cancel(adns_state ads, adns_query query);
 
 int adns_finish(adns_state);
+/* You may call this even if you have queries outstanding;
+ * they will be cancelled.
+ */
 
 int adns_callback(adns_state, int maxfd, const fd_set *readfds, const fd_set *writefds,
                  const fd_set *exceptfds);
 
 int adns_callback(adns_state, int maxfd, const fd_set *readfds, const fd_set *writefds,
                  const fd_set *exceptfds);
index 7a28e01b0cfd102927c6ec9337deb1ef07d925ba..dcf0adb0c5f7dced70a0333cbf63cbdbe5c85ab6 100644 (file)
@@ -1,4 +1,26 @@
-/**/
+/*
+ * event.c
+ * - event loop core
+ * - TCP connection management
+ * - user-visible check/wait and event-loop-related functions
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #include <string.h>
 #include <errno.h>
 
 #include <string.h>
 #include <errno.h>
diff --git a/src/general.c b/src/general.c
new file mode 100644 (file)
index 0000000..7c42eb6
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * general.c
+ * - diagnostic functions
+ * - vbuf handling
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#include "internal.h"
+
+/* Core diagnostic functions */
+
+void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
+                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;
+
+  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) {
+    fprintf(stderr,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr));
+    bef=", "; aft=")\n";
+  }
+
+  fputs(aft,stderr);
+}
+
+void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
+  va_list al;
+
+  va_start(al,fmt);
+  adns__vdiag(ads," debug",0,serv,qu,fmt,al);
+  va_end(al);
+}
+
+void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
+  va_list al;
+
+  va_start(al,fmt);
+  adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al);
+  va_end(al);
+}
+
+void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
+  va_list al;
+
+  va_start(al,fmt);
+  adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al);
+  va_end(al);
+}
+
+/* vbuf functions */
+
+void adns__vbuf_init(vbuf *vb) {
+  vb->used= vb->avail= 0; vb->buf= 0;
+}
+
+int adns__vbuf_ensure(vbuf *vb, int want) {
+  void *nb;
+  
+  if (vb->avail >= want) return 1;
+  nb= realloc(vb->buf,want); if (!nb) return 0;
+  vb->buf= nb;
+  vb->avail= want;
+  return 1;
+}
+  
+void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) {
+  memcpy(vb->buf+vb->used,data,len);
+  vb->used+= len;
+}
+
+int adns__vbuf_append(vbuf *vb, const byte *data, int len) {
+  int newlen;
+  void *nb;
+
+  newlen= vb->used+len;
+  if (vb->avail < newlen) {
+    newlen <<= 1;
+    nb= realloc(vb->buf,newlen);
+    if (!nb) { newlen >>= 1; nb= realloc(vb->buf,newlen); }
+    if (!nb) return 0;
+    vb->buf= nb;
+    vb->avail= newlen;
+  }
+  adns__vbuf_appendq(vb,data,len);
+  return 1;
+}
+
+/* Additional diagnostic functions */
+
+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);
+  if (st == adns_s_nomemory) {
+    return "<cannot report domain... out of memory>";
+  }
+  if (st) {
+    vb->used= 0;
+    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 ...>");
+    adns__vbuf_append(vb,"",1);
+  }
+  return vb->buf;
+}
+    
+const char *adns_strerror(adns_status st) {
+  static char buf[100];
+  snprintf(buf,sizeof(buf),"code %d",st);
+  return buf;
+}
index 58d4a4c7c52c417bbad06db530a7a3b9031cc7b7..61f2ff73ddc4681427975c72c72dfdc86cdbdd3f 100644 (file)
@@ -1,4 +1,26 @@
-/**/
+/*
+ * internal.h
+ * - declarations of private objects with external linkage (adns__*)
+ * - definitons of internal macros
+ * - comments regarding library data structures
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #ifndef ADNS_INTERNAL_H_INCLUDED
 #define ADNS_INTERNAL_H_INCLUDED
 
 #ifndef ADNS_INTERNAL_H_INCLUDED
 #define ADNS_INTERNAL_H_INCLUDED
@@ -200,6 +222,10 @@ struct adns__state {
 
 /* From setup.c: */
 
 
 /* From setup.c: */
 
+int adns__setnonblock(adns_state ads, int fd); /* => errno value */
+
+/* From general.c: */
+
 void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
                 int serv, adns_query qu, const char *fmt, va_list al);
 
 void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
                 int serv, adns_query qu, const char *fmt, va_list al);
 
@@ -218,9 +244,46 @@ void adns__vbuf_appendq(vbuf *vb, const byte *data, int len);
 void adns__vbuf_init(vbuf *vb);
 void adns__vbuf_free(vbuf *vb);
 
 void adns__vbuf_init(vbuf *vb);
 void adns__vbuf_free(vbuf *vb);
 
-int adns__setnonblock(adns_state ads, int fd); /* => errno value */
+const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb,
+                             int flags, const byte *dgram, int dglen, int cbyte);
+/* Unpicks a domain in a datagram and returns a string suitable for
+ * printing it as.  Never fails - if an error occurs, it will
+ * return some kind of string describing the error.
+ *
+ * serv may be -1, qu may be 0.  vb must have been initialised,
+ * and will be left in an arbitrary consistent state.
+ *
+ * Returns either vb->buf, or a pointer to a string literal.  Do not modify
+ * vb before using the return value.
+ */
+  
+/* From transmit.c: */
 
 
-/* From submit.c: */
+adns_status adns__mkquery(adns_state ads, vbuf *vb,
+                         const char *owner, int ol, int *id_r,
+                         const typeinfo *typei, adns_queryflags flags);
+/* Assembles a query packet in vb, and returns id at *id_r. */
+
+void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now);
+/* Query must be in state tcpwait/timew; it will be moved to a new state
+ * if possible and no further processing can be done on it for now.
+ * (Resulting state is one of tcpwait/timew (if server not connected),
+ *  tcpsent/timew, child/childw or done/output.)
+ *
+ * adns__tcp_tryconnect should already have been called - _tcp
+ * will only use an existing connection (if there is one), which it
+ * may break.  If the conn list lost then the caller is responsible for any
+ * reestablishment and retry.
+ */
+
+void adns__query_udp(adns_state ads, adns_query qu, struct timeval now);
+/* Query must be in state udp/NONE; it will be moved to a new state,
+ * and no further processing can be done on it for now.
+ * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected),
+ *  tcpsent/timew, child/childw or done/output.)
+ */
+
+/* From query.c: */
 
 int adns__internal_submit(adns_state ads, adns_query *query_r,
                          adns_rrtype type, vbuf *qumsg_vb, int id,
 
 int adns__internal_submit(adns_state ads, adns_query *query_r,
                          adns_rrtype type, vbuf *qumsg_vb, int id,
@@ -261,18 +324,6 @@ void *adns__alloc_final(adns_query qu, size_t sz);
 void adns__makefinal_block(adns_query qu, void **blpp, size_t sz);
 void adns__makefinal_str(adns_query qu, char **strp);
 
 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);
-adns_status adns__mkquery(adns_state ads, vbuf *vb,
-                         const char *owner, int ol, int *id_r,
-                         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__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
 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
@@ -280,6 +331,9 @@ void adns__reset_cnameonly(adns_state ads, adns_query qu);
  * when we're halfway through RRs in a datagram and discover that we
  * need to retry the query.
  */
  * when we're halfway through RRs in a datagram and discover that we
  * need to retry the query.
  */
+
+void adns__query_done(adns_state ads, adns_query qu);
+void adns__query_fail(adns_state ads, adns_query qu, adns_status stat);
    
 /* From reply.c: */
 
    
 /* From reply.c: */
 
@@ -382,7 +436,9 @@ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len);
 
 void adns__tcp_broken(adns_state ads, const char *what, const char *why);
 void adns__tcp_tryconnect(adns_state ads, struct timeval now);
 
 void adns__tcp_broken(adns_state ads, const char *what, const char *why);
 void adns__tcp_tryconnect(adns_state ads, struct timeval now);
+
 void adns__autosys(adns_state ads, struct timeval now);
 void adns__autosys(adns_state ads, struct timeval now);
+/* Make all the system calls we want to if the application wants us to. */
 
 /* Useful static inline functions: */
 
 
 /* Useful static inline functions: */
 
index 9691dccaa1ed789e66ea6a59f956658b683bf51c..bf04d4d2ef089c85c90fd42d048cea1665ae6601 100644 (file)
@@ -1,4 +1,24 @@
-/**/
+/*
+ * parse.c
+ * - parsing assistance functions (mainly for domains inside datagrams)
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #include "internal.h"
 
 
 #include "internal.h"
 
@@ -120,30 +140,6 @@ 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, 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);
-  if (st == adns_s_nomemory) {
-    return "<cannot report domain... out of memory>";
-  }
-  if (st) {
-    vb->used= 0;
-    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 ...>");
-    adns__vbuf_append(vb,"",1);
-  }
-  return vb->buf;
-}
-    
 adns_status adns__findrr(adns_state ads, int serv,
                         const byte *dgram, int dglen, int *cbyte_io,
                         int *type_r, int *class_r, int *rdlen_r, int *rdstart_r,
 adns_status adns__findrr(adns_state ads, int serv,
                         const byte *dgram, int dglen, int *cbyte_io,
                         int *type_r, int *class_r, int *rdlen_r, int *rdstart_r,
index 890757ec692fa3d20eedcce75f2088935cc9d4ed..7f65bc11b24fbc1d451b103555eab8c19a84721c 100644 (file)
-/**/
-
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <sys/uio.h>
+/*
+ * query.c
+ * - overall query management (allocation, completion)
+ * - per-query memory management
+ * - query submission and cancellation (user-visible and internal)
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #include "internal.h"
 
 
 #include "internal.h"
 
-adns_status adns__mkquery(adns_state ads, vbuf *vb,
-                         const char *owner, int ol, int *id_r,
-                         const typeinfo *typei, adns_queryflags flags) {
-  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))
-
-  vb->used= 0;
-  if (!adns__vbuf_ensure(vb,DNS_HDRSIZE+strlen(owner)+1+5))
-    return adns_s_nolocalmem;
-  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_ADDB(0x00); /* !RA, Z=000, RCODE=NOERROR(0000) */
-  MKQUERY_ADDW(1); /* QDCOUNT=1 */
-  MKQUERY_ADDW(0); /* ANCOUNT=0 */
-  MKQUERY_ADDW(0); /* NSCOUNT=0 */
-  MKQUERY_ADDW(0); /* ARCOUNT=0 */
-  p= owner; pe= owner+ol;
-  nlabs= 0;
-  if (!*p) return adns_s_invaliddomain;
-  do {
-    ll= 0;
-    while (p!=pe && (c= *p++)!='.') {
-      if (c=='\\') {
-       if (!(flags & adns_qf_anyquote)) return adns_s_invaliddomain;
-       if (ctype_digit(p[0])) {
-         if (ctype_digit(p[1]) && ctype_digit(p[2])) {
-           c= (*p++ - '0')*100 + (*p++ - '0')*10 + (*p++ - '0');
-           if (c >= 256) return adns_s_invaliddomain;
-         } else {
-           return adns_s_invaliddomain;
-         }
-       } else if (!(c= *p++)) {
-         return adns_s_invaliddomain;
-       }
-      }
-      if (!(flags & adns_qf_anyquote)) {
-       if (ctype_digit(c) || c == '-') {
-         if (!ll) return adns_s_invaliddomain;
-       } else if (!ctype_alpha(c)) {
-         return adns_s_invaliddomain;
-       }
-      }
-      if (ll == sizeof(label)) return adns_s_invaliddomain;
-      label[ll++]= c;
-    }
-    if (!ll) return adns_s_invaliddomain;
-    if (nlabs++ > 63) return adns_s_invaliddomain;
-    MKQUERY_ADDB(ll);
-    memcpy(rqp,label,ll); rqp+= ll;
-  } while (p!=pe);
-
-  MKQUERY_ADDB(0);
-  MKQUERY_ADDW(typei->type & adns__rrt_typemask); /* QTYPE */
-  MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */
-
-  vb->used= rqp - vb->buf;
-  assert(vb->used <= vb->avail);
-  
-  return adns_s_ok;
-}
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
 
 
-void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) {
-  /* Query must be in state tcpwait/timew; it will be moved to a new state
-   * if possible and no further processing can be done on it for now.
-   * (Resulting state is one of tcpwait/timew (if server not connected),
-   *  tcpsent/timew, child/childw or done/output.)
-   *
-   * adns__tcp_tryconnect should already have been called - _tcp
-   * will only use an existing connection (if there is one), which it
-   * may break.  If the conn list lost then the caller is responsible for any
-   * reestablishment and retry.
-   */
-  byte length[2];
-  struct iovec iov[2];
-  int wr, r;
+#include <sys/time.h>
 
 
-  if (ads->tcpstate != server_ok) return;
+#include "internal.h"
 
 
-  length[0]= (qu->query_dglen&0x0ff00U) >>8;
-  length[1]= (qu->query_dglen&0x0ff);
+int adns__internal_submit(adns_state ads, adns_query *query_r,
+                         adns_rrtype type, vbuf *qumsg_vb, int id,
+                         adns_queryflags flags, struct timeval now,
+                         adns_status failstat, const qcontext *ctx) {
+  adns_query qu;
+  adns_status stat;
+  int ol, id, r;
+  struct timeval now;
+  const typeinfo *typei;
+  adns_query qu;
+
+  qu= malloc(sizeof(*qu)); if (!qu) goto x_nomemory;
+  qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) goto x_freequ_nomemory;
+
+  qu->state= query_udp;
+  qu->back= qu->next= qu->parent= 0;
+  LIST_INIT(qu->children);
+  qu->siblings.next= qu->siblings.back= 0;
+  qu->allocations= 0;
+  qu->interim_allocd= 0;
+  qu->perm_used= 0;
+
+  qu->typei= adns__findtype(type);
+  adns__vbuf_init(&qu->vb);
+
+  qu->cname_dgram= 0;
+  qu->cname_dglen= qu->cname_begin= 0;
   
   
-  if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->query_dglen+2)) return;
-
-  timevaladd(&now,TCPMS);
-  qu->timeout= now;
-  qu->state= query_tcpsent;
-  LIST_LINK_TAIL(ads->timew,qu);
+  qu->id= id;
+  qu->flags= flags;
+  qu->udpretries= 0;
+  qu->udpnextserver= 0;
+  qu->udpsent= qu->tcpfailed= 0;
+  timerclear(&qu->timeout);
+  memcpy(&qu->context,ctx,sizeof(qu->context));
+  memcpy(qu->owner,owner,ol); qu->owner[ol]= 0;
+
+  qu->answer->status= adns_s_ok;
+  qu->answer->cname= 0;
+  qu->answer->type= type;
+  qu->answer->nrrs= 0;
+  qu->answer->rrs= 0;
 
 
-  if (ads->tcpsend.used) {
-    wr= 0;
+  if (qu->typei) {
+    qu->answer->rrsz= qu->rrsz;
   } else {
   } else {
-    iov[0].iov_base= length;
-    iov[0].iov_len= 2;
-    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 ||
-           errno == ENOBUFS || errno == ENOMEM)) {
-       adns__tcp_broken(ads,"write",strerror(errno));
-       return;
-      }
-      wr= 0;
-    }
+    qu->answer->rrsz= -1;
+    failstat= adns_s_notimplemented;
   }
   }
+  
+  *query_r= qu;
 
 
-  if (wr<2) {
-    r= adns__vbuf_append(&ads->tcpsend,length,2-wr); assert(r);
-    wr= 0;
-  } else {
-    wr-= 2;
+  qu->query_dgram= malloc(qumsg_vb->used);
+  if (!qu->query_dgram) {
+    adns__query_fail(ads,qu,adns_s_nomemory);
+    return;
   }
   }
-  if (wr<qu->query_dglen) {
-    r= adns__vbuf_append(&ads->tcpsend,qu->query_dgram+wr,qu->query_dglen-wr); assert(r);
+  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;
   }
   }
+  adns__query_udp(ads,qu,now);
+  adns__autosys(ads,now);
+
+  return 0;
+
+ x_freequ_nomemory:
+  free(qu);
+ x_nomemory:
+  free(query_dgram);
+  return adns_s_nomemory;
 }
 
 }
 
-static void query_usetcp(adns_state ads, adns_query qu, struct timeval now) {
-  timevaladd(&now,TCPMS);
-  qu->timeout= now;
-  qu->state= query_tcpwait;
-  LIST_LINK_TAIL(ads->timew,qu);
-  adns__query_tcp(ads,qu,now);
-  adns__tcp_tryconnect(ads,now);
+int adns_submit(adns_state ads,
+               const char *owner,
+               adns_rrtype type,
+               adns_queryflags flags,
+               void *context,
+               adns_query *query_r) {
+  qcontext ctx;
+  int id;
+  vbuf vb;
+
+  ctx.ext= context;
+  r= gettimeofday(&now,0); if (r) return errno;
+  id= 0;
+
+  adns__vbuf_init(&vb);
+
+  ol= strlen(owner);
+  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--; }
+
+  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);        
 }
 
 }
 
-void adns__query_udp(adns_state ads, adns_query qu, struct timeval now) {
-  /* Query must be in state udp/NONE; it will be moved to a new state,
-   * and no further processing can be done on it for now.
-   * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected),
-   *  tcpsent/timew, child/childw or done/output.)
-   */
-  struct sockaddr_in servaddr;
-  int serv, r;
+int adns_synchronous(adns_state ads,
+                    const char *owner,
+                    adns_rrtype type,
+                    adns_queryflags flags,
+                    adns_answer **answer_r) {
+  adns_query qu;
+  int r;
+  
+  r= adns_submit(ads,owner,type,flags,0,&qu);
+  if (r) return r;
 
 
-  assert(qu->state == query_udp);
-  if ((qu->flags & adns_qf_usevc) || (qu->query_dglen > DNS_MAXUDP)) {
-    query_usetcp(ads,qu,now);
-    return;
-  }
+  do {
+    r= adns_wait(ads,&qu,answer_r,0);
+  } while (r==EINTR);
+  if (r) adns_cancel(ads,qu);
+  return r;
+}
 
 
-  if (qu->udpretries >= UDPMAXRETRIES) {
-    adns__query_fail(ads,qu,adns_s_timeout);
-    return;
+void adns_cancel(adns_state ads, adns_query query) {
+  abort(); /* fixme */
+}
+
+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) {
+    adns__query_fail(ads,qu,adns_s_nolocalmem);
+    return 0;
   }
   }
+  qu->permalloclen += sz;
+  an->next= qu->allocations;
+  qu->allocations= an;
+  return (byte*)an + MEM_ROUND(sizeof(*an));
+}
 
 
-  serv= qu->udpnextserver;
-  memset(&servaddr,0,sizeof(servaddr));
-  servaddr.sin_family= AF_INET;
-  servaddr.sin_addr= ads->servers[serv].addr;
-  servaddr.sin_port= htons(DNS_PORT);
-  
-  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) adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno));
-  
-  timevaladd(&now,UDPRETRYMS);
-  qu->timeout= now;
-  qu->udpsent |= (1<<serv);
-  qu->udpnextserver= (serv+1)%ads->nservers;
-  qu->udpretries++;
-  LIST_LINK_TAIL(ads->timew,qu);
+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;
+}
+
+void adns__reset_cnameonly(adns_state ads, adns_query qu) {
+  assert(qu->final_allocspace);
+  qu->answer->nrrs= 0;
+  qu->answer->rrs= 0;
+  qu->interim_allocd= qu->answer->cname ? MEM_ROUND(strlen(qu->answer->cname)+1) : 0;
 }
 
 static void adns__query_done(adns_state ads, adns_query qu) {
 }
 
 static void adns__query_done(adns_state ads, adns_query qu) {
@@ -205,15 +222,28 @@ static void adns__query_done(adns_state ads, adns_query qu) {
   LIST_LINK_TAIL(ads->output,qu);
 }
 
   LIST_LINK_TAIL(ads->output,qu);
 }
 
-void adns__reset_cnameonly(adns_state ads, adns_query qu) {
-  assert(qu->final_allocspace);
-  qu->answer->nrrs= 0;
-  qu->answer->rrs= 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;
   adns__query_done(ads,qu);
 }
 void adns__query_fail(adns_state ads, adns_query qu, adns_status stat) {
   adns__reset_cnameonly(ads,qu);
   qu->answer->status= stat;
   adns__query_done(ads,qu);
 }
+
+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;
+}
+
index 198218e97ecc2944ed3456e4455d3d1d1fdf8c2b..337d3f8e2d6187e17877445deb0f010cc5170e48 100644 (file)
@@ -1,4 +1,24 @@
-/**/
+/*
+ * reply.c
+ * - main handling and parsing routine for received datagrams
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #include "internal.h"
 
 
 #include "internal.h"
 
@@ -254,7 +274,7 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
   adns__query_finish(ads,qu,adns_s_ok);
   return;
 
   adns__query_finish(ads,qu,adns_s_ok);
   return;
 
-x_truncated:
+ x_truncated:
   if (!flg_tc) {
     adns__diag(ads,serv,qu,"server sent datagram which points outside itself");
     adns__query_fail(ads,qu,adns_s_serverfaulty);
   if (!flg_tc) {
     adns__diag(ads,serv,qu,"server sent datagram which points outside itself");
     adns__query_fail(ads,qu,adns_s_serverfaulty);
index 7ea538905149537759aea792444c699541375652..78b8fb3e0d221a89dbd3e4a5f915156e5d777668 100644 (file)
@@ -1,4 +1,25 @@
-/**/
+/*
+ * setup.c
+ * - configuration file parsing
+ * - management of global state
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #include <stdlib.h>
 #include <errno.h>
 
 #include <stdlib.h>
 #include <errno.h>
 
 #include "internal.h"
 
 
 #include "internal.h"
 
-void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
-                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;
-
-  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) {
-    fprintf(stderr,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr));
-    bef=", "; aft=")\n";
-  }
-
-  fputs(aft,stderr);
-}
-
-void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
-  va_list al;
-
-  va_start(al,fmt);
-  adns__vdiag(ads," debug",0,serv,qu,fmt,al);
-  va_end(al);
-}
-
-void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
-  va_list al;
-
-  va_start(al,fmt);
-  adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al);
-  va_end(al);
-}
-
-void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
-  va_list al;
-
-  va_start(al,fmt);
-  adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al);
-  va_end(al);
-}
-
-  
-void adns__vbuf_init(vbuf *vb) {
-  vb->used= vb->avail= 0; vb->buf= 0;
-}
-
-int adns__vbuf_ensure(vbuf *vb, int want) {
-  void *nb;
-  
-  if (vb->avail >= want) return 1;
-  nb= realloc(vb->buf,want); if (!nb) return 0;
-  vb->buf= nb;
-  vb->avail= want;
-  return 1;
-}
-  
-void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) {
-  memcpy(vb->buf+vb->used,data,len);
-  vb->used+= len;
-}
-
-int adns__vbuf_append(vbuf *vb, const byte *data, int len) {
-  int newlen;
-  void *nb;
-
-  newlen= vb->used+len;
-  if (vb->avail < newlen) {
-    newlen <<= 1;
-    nb= realloc(vb->buf,newlen);
-    if (!nb) { newlen >>= 1; nb= realloc(vb->buf,newlen); }
-    if (!nb) return 0;
-    vb->buf= nb;
-    vb->avail= newlen;
-  }
-  adns__vbuf_appendq(vb,data,len);
-  return 1;
-}
-
-
 static void addserver(adns_state ads, struct in_addr addr) {
   int i;
   struct server *ss;
 static void addserver(adns_state ads, struct in_addr addr) {
   int i;
   struct server *ss;
@@ -323,9 +252,3 @@ int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) {
 int adns_finish(adns_state ads) {
   abort(); /* fixme */
 }
 int adns_finish(adns_state ads) {
   abort(); /* fixme */
 }
-
-const char *adns_strerror(adns_status st) {
-  static char buf[100];
-  snprintf(buf,sizeof(buf),"code %d",st);
-  return buf;
-}
diff --git a/src/submit.c b/src/submit.c
deleted file mode 100644 (file)
index 197381d..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/**/
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/time.h>
-
-#include "internal.h"
-
-int adns__internal_submit(adns_state ads, adns_query *query_r,
-                         adns_rrtype type, vbuf *qumsg_vb, int id,
-                         adns_queryflags flags, struct timeval now,
-                         adns_status failstat, const qcontext *ctx) {
-  adns_query qu;
-  adns_status stat;
-  int ol, id, r;
-  struct timeval now;
-  const typeinfo *typei;
-  adns_query qu;
-
-  qu= malloc(sizeof(*qu)); if (!qu) goto x_nomemory;
-  qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) goto x_freequ_nomemory;
-
-  qu->state= query_udp;
-  qu->back= qu->next= qu->parent= 0;
-  LIST_INIT(qu->children);
-  qu->siblings.next= qu->siblings.back= 0;
-  qu->allocations= 0;
-  qu->interim_allocd= 0;
-  qu->perm_used= 0;
-
-  qu->typei= adns__findtype(type);
-  adns__vbuf_init(&qu->vb);
-
-  qu->cname_dgram= 0;
-  qu->cname_dglen= qu->cname_begin= 0;
-  
-  qu->id= id;
-  qu->flags= flags;
-  qu->udpretries= 0;
-  qu->udpnextserver= 0;
-  qu->udpsent= qu->tcpfailed= 0;
-  timerclear(&qu->timeout);
-  memcpy(&qu->context,ctx,sizeof(qu->context));
-  memcpy(qu->owner,owner,ol); qu->owner[ol]= 0;
-
-  qu->answer->status= adns_s_ok;
-  qu->answer->cname= 0;
-  qu->answer->type= type;
-  qu->answer->nrrs= 0;
-  qu->answer->rrs= 0;
-
-  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;
-  }
-  adns__query_udp(ads,qu,now);
-  adns__autosys(ads,now);
-
-  return 0;
-
- x_freequ_nomemory:
-  free(qu);
- x_nomemory:
-  free(query_dgram);
-  return adns_s_nomemory;
-}
-
-int adns_submit(adns_state ads,
-               const char *owner,
-               adns_rrtype type,
-               adns_queryflags flags,
-               void *context,
-               adns_query *query_r) {
-  qcontext ctx;
-  int id;
-  vbuf vb;
-
-  ctx.ext= context;
-  r= gettimeofday(&now,0); if (r) return errno;
-  id= 0;
-
-  adns__vbuf_init(&vb);
-
-  ol= strlen(owner);
-  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--; }
-
-  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,
-                    const char *owner,
-                    adns_rrtype type,
-                    adns_queryflags flags,
-                    adns_answer **answer_r) {
-  adns_query qu;
-  int r;
-  
-  r= adns_submit(ads,owner,type,flags,0,&qu);
-  if (r) return r;
-
-  do {
-    r= adns_wait(ads,&qu,answer_r,0);
-  } while (r==EINTR);
-  if (r) adns_cancel(ads,qu);
-  return r;
-}
-
-void adns_cancel(adns_state ads, adns_query query) {
-  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;
-
-  assert(!qu->final_allocspace);
-  sz= MEM_ROUND(sz);
-  an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz));
-  if (!an) {
-    adns__query_fail(ads,qu,adns_s_nolocalmem);
-    return 0;
-  }
-  qu->permalloclen += sz;
-  an->next= qu->allocations;
-  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;
-}
diff --git a/src/transmit.c b/src/transmit.c
new file mode 100644 (file)
index 0000000..2633bdc
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * transmit.c
+ * - construct queries
+ * - send queries
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#include "internal.h"
+
+adns_status adns__mkquery(adns_state ads, vbuf *vb,
+                         const char *owner, int ol, int *id_r,
+                         const typeinfo *typei, adns_queryflags flags) {
+  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))
+
+  vb->used= 0;
+  if (!adns__vbuf_ensure(vb,DNS_HDRSIZE+strlen(owner)+1+5))
+    return adns_s_nolocalmem;
+  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_ADDB(0x00); /* !RA, Z=000, RCODE=NOERROR(0000) */
+  MKQUERY_ADDW(1); /* QDCOUNT=1 */
+  MKQUERY_ADDW(0); /* ANCOUNT=0 */
+  MKQUERY_ADDW(0); /* NSCOUNT=0 */
+  MKQUERY_ADDW(0); /* ARCOUNT=0 */
+  p= owner; pe= owner+ol;
+  nlabs= 0;
+  if (!*p) return adns_s_invaliddomain;
+  do {
+    ll= 0;
+    while (p!=pe && (c= *p++)!='.') {
+      if (c=='\\') {
+       if (!(flags & adns_qf_anyquote)) return adns_s_invaliddomain;
+       if (ctype_digit(p[0])) {
+         if (ctype_digit(p[1]) && ctype_digit(p[2])) {
+           c= (*p++ - '0')*100 + (*p++ - '0')*10 + (*p++ - '0');
+           if (c >= 256) return adns_s_invaliddomain;
+         } else {
+           return adns_s_invaliddomain;
+         }
+       } else if (!(c= *p++)) {
+         return adns_s_invaliddomain;
+       }
+      }
+      if (!(flags & adns_qf_anyquote)) {
+       if (ctype_digit(c) || c == '-') {
+         if (!ll) return adns_s_invaliddomain;
+       } else if (!ctype_alpha(c)) {
+         return adns_s_invaliddomain;
+       }
+      }
+      if (ll == sizeof(label)) return adns_s_invaliddomain;
+      label[ll++]= c;
+    }
+    if (!ll) return adns_s_invaliddomain;
+    if (nlabs++ > 63) return adns_s_invaliddomain;
+    MKQUERY_ADDB(ll);
+    memcpy(rqp,label,ll); rqp+= ll;
+  } while (p!=pe);
+
+  MKQUERY_ADDB(0);
+  MKQUERY_ADDW(typei->type & adns__rrt_typemask); /* QTYPE */
+  MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */
+
+  vb->used= rqp - vb->buf;
+  assert(vb->used <= vb->avail);
+  
+  return adns_s_ok;
+}
+
+void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) {
+  byte length[2];
+  struct iovec iov[2];
+  int wr, r;
+
+  if (ads->tcpstate != server_ok) return;
+
+  length[0]= (qu->query_dglen&0x0ff00U) >>8;
+  length[1]= (qu->query_dglen&0x0ff);
+  
+  if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->query_dglen+2)) return;
+
+  timevaladd(&now,TCPMS);
+  qu->timeout= now;
+  qu->state= query_tcpsent;
+  LIST_LINK_TAIL(ads->timew,qu);
+
+  if (ads->tcpsend.used) {
+    wr= 0;
+  } else {
+    iov[0].iov_base= length;
+    iov[0].iov_len= 2;
+    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 ||
+           errno == ENOBUFS || errno == ENOMEM)) {
+       adns__tcp_broken(ads,"write",strerror(errno));
+       return;
+      }
+      wr= 0;
+    }
+  }
+
+  if (wr<2) {
+    r= adns__vbuf_append(&ads->tcpsend,length,2-wr); assert(r);
+    wr= 0;
+  } else {
+    wr-= 2;
+  }
+  if (wr<qu->query_dglen) {
+    r= adns__vbuf_append(&ads->tcpsend,qu->query_dgram+wr,qu->query_dglen-wr); assert(r);
+  }
+}
+
+static void query_usetcp(adns_state ads, adns_query qu, struct timeval now) {
+  timevaladd(&now,TCPMS);
+  qu->timeout= now;
+  qu->state= query_tcpwait;
+  LIST_LINK_TAIL(ads->timew,qu);
+  adns__query_tcp(ads,qu,now);
+  adns__tcp_tryconnect(ads,now);
+}
+
+void adns__query_udp(adns_state ads, adns_query qu, struct timeval now) {
+  struct sockaddr_in servaddr;
+  int serv, r;
+
+  assert(qu->state == query_udp);
+  if ((qu->flags & adns_qf_usevc) || (qu->query_dglen > DNS_MAXUDP)) {
+    query_usetcp(ads,qu,now);
+    return;
+  }
+
+  if (qu->udpretries >= UDPMAXRETRIES) {
+    adns__query_fail(ads,qu,adns_s_timeout);
+    return;
+  }
+
+  serv= qu->udpnextserver;
+  memset(&servaddr,0,sizeof(servaddr));
+  servaddr.sin_family= AF_INET;
+  servaddr.sin_addr= ads->servers[serv].addr;
+  servaddr.sin_port= htons(DNS_PORT);
+  
+  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) adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno));
+  
+  timevaladd(&now,UDPRETRYMS);
+  qu->timeout= now;
+  qu->udpsent |= (1<<serv);
+  qu->udpnextserver= (serv+1)%ads->nservers;
+  qu->udpretries++;
+  LIST_LINK_TAIL(ads->timew,qu);
+}
index 38330cf11a45e9dd04c27901beb8ab66e2e0a126..45741fa36cee820080a584cfa1bac145194738fa 100644 (file)
@@ -1,4 +1,24 @@
-/**/
+/*
+ * types.c
+ * - RR-type-specific code, and the machinery to call it
+ */
+/*
+ *  This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
 
 #include "internal.h"
 
 
 #include "internal.h"