chiark / gitweb /
New init flags and options to influence address family selection.
[adns.git] / src / adns.h
index 3989f4fe50f91037312bdba68275c9fb0e539b39..e5063b76b8ca0e921dd5cc571e477c472d256b26 100644 (file)
 extern "C" { /* I really dislike this - iwj. */
 #endif
 
+/* Whether to support address families other than IPv4 in responses which use
+ * the `adns_rr_addr' structure.  This is a source-compatibility issue: old
+ * clients may not expect to find address families other than AF_INET in
+ * their query results.  There's a separate binary compatibility issue to do
+ * with the size of the `adns_rr_addr' structure, but we'll assume you can
+ * cope with that because you have this header file.  Define
+ * `ADNS_FEATURE_IPV4ONLY' if you only want to see AF_INET addresses, or
+ * `ADNS_FEATURE_MANYAF' to allow multiple address families; the default is
+ * currently to stick with AF_INET only, but this is likely to change in a
+ * later release of ADNS.
+ */
+#if !defined(ADNS_FEATURE_IPV4ONLY) && !defined(ADNS_FEATURE_MANYAF)
+#  define ADNS_FEATURE_IPV4ONLY
+#elif defined(ADNS_FEATURE_IPV4ONLY) && defined(ADNS_FEATURE_MANYAF)
+#  error "Feature flags ADNS_FEATURE_IPV4ONLY and ..._MANYAF are incompatible"
+#endif
+
 /* All struct in_addr anywhere in adns are in NETWORK byte order. */
 
 typedef struct adns__state *adns_state;
@@ -87,7 +104,18 @@ typedef enum { /* In general, or together the desired flags: */
  adns_if_eintr=       0x0020,/* allow _wait and _synchronous to return EINTR */
  adns_if_nosigpipe=   0x0040,/* applic has SIGPIPE ignored, do not protect */
  adns_if_checkc_entex=0x0100,/* consistency checks on entry/exit to adns fns */
- adns_if_checkc_freq= 0x0300 /* consistency checks very frequently (slow!) */
+ adns_if_checkc_freq= 0x0300,/* consistency checks very frequently (slow!) */
+
+ adns_if_af_v4only=   0x0400,/* only return IPv4 addresses, given the choice */
+ adns_if_af_v6only=   0x0800,/* only return IPv6 addresses, ... */
+ adns_if_afmask=      adns_if_af_v4only|adns_if_af_v6only
+   /* Only set one of these.  They are policy flags, and overridden by the
+    * adns_af:... options in resolv.conf.  If the adns_qf_ipv... query
+    * flags are incompatible with these settings (in the sense that no
+    * address families are permitted at all) then the query flags take
+    * precedence; otherwise only records which satisfy all of the stated
+    * requirements are allowed.
+    */
 } adns_initflags;
 
 typedef enum { /* In general, or together the desired flags: */
@@ -101,12 +129,19 @@ typedef enum { /* In general, or together the desired flags: */
  adns_qf_quotefail_cname=0x00000080,/* refuse if quote-req chars in CNAME we go via */
  adns_qf_cname_loose=    0x00000100,/* allow refs to CNAMEs - without, get _s_cname */
  adns_qf_cname_forbid=   0x00000200,/* don't follow CNAMEs, instead give _s_cname */
+ adns_qf_ipv4_only=     0x00000400,/* only ever return IPv4 addresses */
+ adns_qf_ipv6_only=     0x00000800,/*  ... and don't bother looking for IPv4 */
+ adns_qf_ipv6_ok=       0x00000c00,/* returning IPv6 addresses is acceptable */
+ adns_qf_domapv4=       0x00001000,/*  ... any IPv4 addresses should be v6-mapped */
+ adns_qf_ipv6_mapv4=    adns_qf_ipv6_ok|adns_qf_domapv4,
+ adns__qf_afmask=       0x00001c00,/* all the above flag bits */
  adns__qf_internalmask=  0x0ff00000
 } adns_queryflags;
 
 typedef enum {
  adns_rrt_typemask=  0x0ffff,
- adns__qtf_deref=    0x10000,/* dereference domains; perhaps get extra data */
+ adns_rrt_reprmask= 0xffffff,
+ adns__qtf_deref_bit=0x10000,/* internal version of ..._deref below */
  adns__qtf_mail822=  0x20000,/* return mailboxes in RFC822 rcpt field fmt   */
 
  adns_r_unknown=     0x40000,
@@ -127,6 +162,15 @@ typedef enum {
     *
     * Don't forget adns_qf_quoteok if that's what you want. */
 
+ adns__qtf_bigaddr=0x1000000,/* use the new larger sockaddr union */
+ adns__qtf_manyaf= 0x2000000,/* permitted to return multiple address families */
+
+ adns__qtf_deref=    adns__qtf_deref_bit|adns__qtf_bigaddr
+#ifdef ADNS_FEATURE_MANYAF
+                    |adns__qtf_manyaf
+#endif
+                           ,/* dereference domains; perhaps get extra data */
+
  adns_r_none=             0,
                     
  adns_r_a=                1,
@@ -284,14 +328,28 @@ typedef enum {
  
 } adns_status;
 
+typedef union {
+  struct sockaddr sa;
+  struct sockaddr_in inet;
+} adns_sockaddr_v4only;
+
+typedef union {
+  struct sockaddr sa;
+  struct sockaddr_in inet;
+  struct sockaddr_in6 inet6;
+  char adns__padding[240]; /* Good idea?  I'm inclined to think not. */
+} adns_sockaddr;
+
 typedef struct {
   int len;
-  union {
-    struct sockaddr sa;
-    struct sockaddr_in inet;
-  } addr;
+  adns_sockaddr addr;
 } adns_rr_addr;
 
+typedef struct {
+  int len;
+  adns_sockaddr_v4only addr;
+} adns_rr_addr_v4only;
+
 typedef struct {
   char *host;
   adns_status astatus;
@@ -508,6 +566,17 @@ int adns_init_logfn(adns_state *newstate_r, adns_initflags flags,
  *   Changes the consistency checking frequency; this overrides the
  *   setting of adns_if_check_entex, adns_if_check_freq, or neither,
  *   in the flags passed to adns_init.
+ *
+ *  adns_af:v4only
+ *  adns_af:v6only
+ *  adns_af:any
+ *   Controls whether ADNS looks for IPv4 (A records) and IPv6 (AAAA
+ *   records) addresses when it's trying to build a socket address.
+ *   The default is `any' which means to allow both.  The `sortlist'
+ *   directive can be used to control the relative preference of IPv4
+ *   and IPv6 addresses if both are returned for the same query.
+ *   These override the corresponding init flags (covered by
+ *   adns_if_afmask).
  * 
  * There are a number of environment variables which can modify the
  * behaviour of adns.  They take effect only if adns_init is used, and