chiark / gitweb /
src/types.c: Start on IPv6 support in adns_r_addr queries.
[adns.git] / src / internal.h
index baf2a295a76643277d0a0bf04808f77166c2e4c1..a95bf4d6a15b79f5ff9955ef015f0a7e863ad835 100644 (file)
@@ -151,6 +151,9 @@ typedef struct {
       adns_rrtype rev_rrtype;
       struct af_addr addr;
     } ptr;
+    struct {
+      unsigned want, have;
+    } addr;
   } tinfo; /* type-specific state for the query itself: zero-init if you
            * don't know better. */
 
@@ -217,6 +220,12 @@ typedef struct typeinfo {
   /* Return the output resource-record element size; if this is null, then
    * the rrsz member can be used.
    */
+
+  void (*query_send)(adns_query qu, struct timeval now);
+  /* Send the query to nameservers, and hook it into the appropriate queue.
+   * Normal behaviour is to call adns__query_send, but this can be overridden
+   * for special effects.
+   */
 } typeinfo;
 
 adns_status adns__ckl_hostname(adns_state ads, adns_queryflags flags,
@@ -229,6 +238,7 @@ adns_status adns__ckl_hostname(adns_state ads, adns_queryflags flags,
 
 typedef struct allocnode {
   struct allocnode *next, *back;
+  size_t sz;
 } allocnode;
 
 union maxalign {
@@ -312,6 +322,10 @@ struct adns__query {
    * Queries in state tcpw/tcpw have been sent (or are in the to-send buffer)
    * iff the tcp connection is in state server_ok.
    *
+   * Internal queries (from adns__submit_internal) end up on intdone
+   * instead of output, and the callbacks are made on the way out of
+   * adns, to avoid reentrancy hazards.
+   *
    *                         +------------------------+
    *             START -----> |      tosend/NONE       |
    *                         +------------------------+
@@ -350,14 +364,18 @@ struct adns__query {
 
 struct query_queue { adns_query head, tail; };
 
+#define MAXUDP 2
+
 struct adns__state {
   adns_initflags iflags;
   adns_logcallbackfn *logfn;
   void *logfndata;
   int configerrno;
-  struct query_queue udpw, tcpw, childw, output;
+  struct query_queue udpw, tcpw, childw, output, intdone;
   adns_query forallnext;
-  int nextid, udpsocket, tcpsocket;
+  int nextid, tcpsocket;
+  struct udpsocket { int af; int fd; } udpsocket[MAXUDP];
+  int nudp;
   vbuf tcpsend, tcprecv;
   int nservers, nsortlist, nsearchlist, searchndots, tcpserver, tcprecv_skip;
   enum adns__tcpstate {
@@ -568,6 +586,15 @@ void adns__querysend_tcp(adns_query qu, struct timeval now);
  * might be broken, but no reconnect will be attempted.
  */
 
+struct udpsocket *adns__udpsocket_by_af(adns_state ads, int af);
+/* Find the UDP socket structure in ads which has the given address family.
+ * Return null if there isn't one.
+ *
+ * This is used during initialization, so ads is only partially filled in.
+ * The requirements are that nudp is set, and that udpsocket[i].af are
+ * defined for 0<=i<nudp.
+ */
+
 void adns__query_send(adns_query qu, struct timeval now);
 /* Query must be in state tosend/NONE; it will be moved to a new state,
  * and no further processing can be done on it for now.
@@ -581,6 +608,7 @@ void adns__query_send(adns_query qu, struct timeval now);
 /* From query.c: */
 
 adns_status adns__internal_submit(adns_state ads, adns_query *query_r,
+                                 adns_query parent,
                                  const typeinfo *typei, adns_rrtype type,
                                  vbuf *qumsg_vb, int id,
                                  adns_queryflags flags, struct timeval now,
@@ -644,8 +672,7 @@ void *adns__alloc_preserved(adns_query qu, size_t sz);
  *  answer->cname and answer->owner are _preserved.
  */
 
-void adns__transfer_interim(adns_query from, adns_query to,
-                           void *block, size_t sz);
+void adns__transfer_interim(adns_query from, adns_query to, void *block);
 /* 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
@@ -659,6 +686,10 @@ void adns__transfer_interim(adns_query from, adns_query to,
  * TTLs get inherited by their parents.
  */
 
+void adns__free_interim(adns_query qu, void *p);
+/* Forget about a block allocated by adns__alloc_interim.
+ */
+
 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
@@ -680,8 +711,18 @@ void adns__reset_preserved(adns_query qu);
  * in a datagram and discover that we need to retry the query.
  */
 
+void adns__cancel(adns_query qu);
 void adns__query_done(adns_query qu);
 void adns__query_fail(adns_query qu, adns_status stat);
+void adns__cancel_children(adns_query qu);
+
+void adns__returning(adns_state ads, adns_query qu);
+/* Must be called before returning from adns any time that we have
+ * progressed (including made, finished or destroyed) queries.
+ *
+ * Might reenter adns via internal query callbacks, so
+ * external-faciing functions which call adns__returning should
+ * normally be avoided in internal code. */
 
 /* From reply.c: */
 
@@ -847,6 +888,7 @@ void adns__autosys(adns_state ads, struct timeval now);
 
 void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
                             struct timeval *tv_buf);
+/* Call with care - might reentrantly cause queries to be completed! */
 
 int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]);
 void adns__fdevents(adns_state ads,