chiark / gitweb /
implement scope flags
[adns.git] / src / adns.h
index 267fd6e66addb293d092ad3f3b0236ae0bdb0d70..9ef45997651177b4f4a7ec132757e965a08a820d 100644 (file)
@@ -66,6 +66,7 @@
 #include <netinet/in.h>
 #include <sys/time.h>
 #include <unistd.h>
+#include <net/if.h>
 
 #ifdef __cplusplus
 extern "C" { /* I really dislike this - iwj. */
@@ -104,7 +105,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: */
@@ -124,6 +136,8 @@ typedef enum { /* In general, or together the desired flags: */
  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_addrlit_scope_forbid=0x00002000,/* forbid %<scope> in IPv6 literals */
+ adns_qf_addrlit_scope_numeric=0x00004000,/* %<scope> may only be numeric */
  adns__qf_internalmask=  0x0ff00000
 } adns_queryflags;
 
@@ -555,6 +569,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
@@ -660,6 +685,60 @@ void adns_finish(adns_state ads);
  * they will be cancelled.
  */
 
+#define ADNS_ADDR2TEXT_BUFLEN                                  \
+  (INET6_ADDRSTRLEN + 1/*%*/                                   \
+  + ((IF_NAMESIZE-1) > 9 ? (IF_NAMESIZE-1) : 9/*uint32*/)      \
+  + 1/* nul; included in IF_NAMESIZE */)
+
+int adns_text2addr(const char *text, uint16_t port, adns_queryflags flags,
+                  struct sockaddr *sa,
+                  socklen_t *salen /* set if OK or ENOSPC; otherwise undef */);
+int adns_addr2text(const struct sockaddr *sa, adns_queryflags flags,
+                  char *buffer, int *buflen /* set iff ENOSPC */,
+                  int *port_r /* may be 0 */);
+  /*
+   * port is always in host byte order and is simply copied to and
+   * from the appropriate sockaddr field (byteswapped as necessary).
+   *
+   * The only flags supported are adns_qf_addrlit_...; others are
+   * ignored.
+   *
+   * Error return values are:
+   *
+   *  ENOSPC    Output buffer is too small.  Can only happen if
+   *            *buflen < ADNS_ADDR2TEXT_BUFLEN or
+   *            *salen < sizeof(adns_sockaddr).  On return,
+   *            *buflen or *salen has been updated by adns.
+   *
+   *  EINVAL    text has invalid syntax.
+   *
+   *            text represents an address family not supported by
+   *            this version of adns.
+   *
+   *            Scoped address supplied (text contained "%" or
+   *            sin6_scope_id nonzero) but caller specified
+   *            adns_qf_addrlit_scope_forbid.
+   *
+   *            Scope name (rather than number) supplied in text but
+   *            caller specified adns_qf_addrlit_scope_numeric.
+   *
+   *  EAFNOSUPPORT   sa->sa_family is not supported (addr2text only).
+   *
+   * Only if neither adns_qf_addrlit_scope_forbid nor
+   * adns_qf_addrlit_scope_numeric are set:
+   *
+   *  ENOSYS    Scope name supplied in text but IPv6 address part of
+   *            sockaddr is not a link local address.
+   *
+   *  ENXIO     Scope name supplied in text but if_nametoindex
+   *            said it wasn't a valid local interface name.
+   *
+   *  EIO       Scoped address supplied but if_nametoindex failed
+   *            in an unexpected way; adns has printed a message to
+   *            stderr.
+   *
+   *  any other   if_nametoindex failed in a more-or-less expected way.
+   */
 
 void adns_forallqueries_begin(adns_state ads);
 adns_query adns_forallqueries_next(adns_state ads, void **context_r);