chiark / gitweb /
Autoconfifying - beginning.
[adns.git] / src / internal.h
index f1f4d9650da70328c9b5c515d55c8b9e797b0594..d878daad34b03f634c68b5c84a5df7ef4074116f 100644 (file)
@@ -25,7 +25,7 @@
 #ifndef ADNS_INTERNAL_H_INCLUDED
 #define ADNS_INTERNAL_H_INCLUDED
 
-#define PRINTFFORMAT(a,b) __attribute__((format(printf,a,b)))
+#include "config.h"
 typedef unsigned char byte;
 
 #include <stdarg.h>
@@ -39,7 +39,8 @@ typedef unsigned char byte;
 /* Configuration and constants */
 
 #define MAXSERVERS 5
-#define UDPMAXRETRIES /*15*/5
+#define MAXSORTLIST 15
+#define UDPMAXRETRIES 15
 #define UDPRETRYMS 2000
 #define TCPMS 30000
 #define LOCALRESOURCEMS 20
@@ -50,6 +51,8 @@ typedef unsigned char byte;
 #define DNS_HDRSIZE 12
 #define DNS_CLASS_IN 1
 
+#define DNS_INADDR_ARPA "in-addr", "arpa"
+
 typedef enum {
   rcode_noerror,
   rcode_formaterror,
@@ -75,11 +78,6 @@ typedef struct {
   byte *buf;
 } vbuf;
 
-typedef union {
-  void *ext;
-  adns_rr_hostaddr *hostaddr;
-} qcontext;
-
 typedef struct {
   adns_state ads;
   adns_query qu;
@@ -118,14 +116,14 @@ typedef struct {
    * nsstart is the offset of the authority section.
    */
 
-  int (*diff_needswap)(const void *datap_a, const void *datap_b);
+  int (*diff_needswap)(adns_state ads, const void *datap_a, const void *datap_b);
   /* Returns !0 if RR a should be strictly after RR b in the sort order,
    * 0 otherwise.  Must not fail.
    */
 } typeinfo;
 
 typedef struct allocnode {
-  struct allocnode *next;
+  struct allocnode *next, *back;
 } allocnode;
 
 union maxalign {
@@ -137,13 +135,22 @@ union maxalign {
   union maxalign *up;
 } data;
 
+typedef struct {
+  void *ext;
+  void (*callback)(adns_query parent, adns_query child);
+  union {
+    adns_rr_addr ptr_parent_addr;
+    adns_rr_hostaddr *hostaddr;
+  } info;
+} qcontext;
+
 struct adns__query {
   adns_state ads;
   enum { query_udp, query_tcpwait, query_tcpsent, query_child, query_done } state;
   adns_query back, next, parent;
   struct { adns_query head, tail; } children;
   struct { adns_query back, next; } siblings;
-  struct allocnode *allocations;
+  struct { allocnode *head, *tail; } allocations;
   int interim_allocd;
   void *final_allocspace;
   
@@ -174,7 +181,8 @@ struct adns__query {
   int udpnextserver;
   unsigned long udpsent, tcpfailed; /* bitmap indexed by server */
   struct timeval timeout;
-  qcontext context;
+
+  qcontext ctx;
 
   /* Possible states:
    *
@@ -232,15 +240,19 @@ struct adns__query {
 struct adns__state {
   adns_initflags iflags;
   FILE *diagfile;
+  int configerrno;
   struct { adns_query head, tail; } timew, childw, output;
   int nextid, udpsocket, tcpsocket;
   vbuf tcpsend, tcprecv;
-  int nservers, tcpserver;
+  int nservers, nsortlist, tcpserver;
   enum adns__tcpstate { server_disconnected, server_connecting, server_ok } tcpstate;
   struct timeval tcptimeout;
   struct server {
     struct in_addr addr;
   } servers[MAXSERVERS];
+  struct sortlist {
+    struct in_addr base, mask;
+  } sortlist[MAXSORTLIST];
 };
 
 /* From setup.c: */
@@ -281,7 +293,8 @@ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu,
  */
   
 void adns__isort(void *array, int nobjs, int sz, void *tempbuf,
-                int (*needswap)(const void *a, const void *b));
+                int (*needswap)(void *context, const void *a, const void *b),
+                void *context);
 /* Does an insertion sort of array which must contain nobjs objects
  * each sz bytes long.  tempbuf must point to a buffer at least
  * sz bytes long.  needswap should return !0 if a>b (strictly, ie
@@ -358,6 +371,16 @@ void *adns__alloc_interim(adns_query qu, size_t sz);
  * but it will not necessarily return a distinct pointer each time.
  */
 
+void adns__transfer_interim(adns_query from, adns_query to, void *block, size_t sz);
+/* Transfers an interim allocation from one query to another, so that
+ * the `to' query will have room for the data when we get to makefinal
+ * and so that the free will happen when the `to' query is freed
+ * rather than the `from' query.
+ *
+ * It is legal to call adns__transfer_interim with a null pointer; this
+ * has no effect.
+ */
+
 void *adns__alloc_mine(adns_query qu, size_t sz);
 /* Like _interim, but does not record the length for later
  * copying into the answer.  This just ensures that the memory
@@ -538,10 +561,10 @@ static inline int ctype_alpha(int c) {
 
 #define LIST_UNLINK_PART(list,node,part) \
   do { \
-    if ((node)->back) (node)->back->part next= (node)->part next; \
-      else                        (list).head= (node)->part next; \
-    if ((node)->next) (node)->next->part back= (node)->part back; \
-      else                        (list).tail= (node)->part back; \
+    if ((node)->part back) (node)->part back->part next= (node)->part next; \
+      else                                  (list).head= (node)->part next; \
+    if ((node)->part next) (node)->part next->part back= (node)->part back; \
+      else                                  (list).tail= (node)->part back; \
   } while(0)
 
 #define LIST_LINK_TAIL_PART(list,node,part) \