chiark / gitweb /
cname_loose/cname_forbid implemented; production timeout
[adns.git] / src / adns.h
index a80081377d31085d3ce5b64aa7df752c61270394..3c06ff6090430a4622c4568f9ec9758bc6e3358f 100644 (file)
@@ -30,6 +30,8 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 
+/* All struct in_addr anywhere in adns are in NETWORK byte order. */
+
 typedef struct adns__state *adns_state;
 typedef struct adns__query *adns_query;
 
@@ -39,58 +41,51 @@ typedef enum {
   adns_if_noserverwarn= 0x0004, /* do not warn to stderr about duff nameservers etc */
   adns_if_debug=        0x0008, /* enable all output to stderr plus debug msgs */
   adns_if_noautosys=    0x0010, /* do not make syscalls at every opportunity */
+  adns_if_eintr=        0x0020, /* allow _wait and _synchronous to return EINTR */
 } adns_initflags;
 
 typedef enum {
-  adns_qf_search=     0x0001, /* use the searchlist */
-  adns_qf_usevc=      0x0002, /* use a virtual circuit (TCP connection) */
-  adns_qf_anyquote=   0x0004,
-  adns_qf_loosecname= 0x0008, /* allow refs to CNAMEs - without, get _s_cname */
-  adns_qf_nocname=    0x0010, /* don't follow CNAMEs, instead give _s_cname */
+  adns_qf_search=          0x000001, /* use the searchlist */
+  adns_qf_usevc=           0x000002, /* use a virtual circuit (TCP connection) */
+  adns_qf_quoteok_query=   0x000010, /* allow quote-requiring chars in query domain */
+  adns_qf_quoteok_cname=   0x000020, /* allow ... in CNAME we go via */
+  adns_qf_quoteok_anshost= 0x000040, /* allow ... in answers expected to be hostnames */
+  adns_qf_cname_loose=     0x000100, /* allow refs to CNAMEs - without, get _s_cname */
+  adns_qf_cname_forbid=    0x000200, /* don't follow CNAMEs, instead give _s_cname */
+  adns__qf_internalmask=   0x0ff000
 } adns_queryflags;
 
 typedef enum {
   adns__rrt_typemask=  0x0ffff,
   adns__qtf_deref=     0x10000, /* dereference domains and perhaps produce extra data */
   adns__qtf_mail822=   0x20000, /* make mailboxes be in RFC822 rcpt field format */
-  adns__qtf_masterfmt= 0x80000, /* convert RRs to master file format, return as str */
   
   adns_r_none=               0,
   
   adns_r_a=                  1,
-  adns_r_a_mf=                  adns_r_a|adns__qtf_masterfmt,
   
   adns_r_ns_raw=             2,
   adns_r_ns=                    adns_r_ns_raw|adns__qtf_deref,
-  adns_r_ns_mf=                 adns_r_ns_raw|adns__qtf_masterfmt,
   
   adns_r_cname=              5,
-  adns_r_cname_mf=              adns_r_cname|adns__qtf_masterfmt,
   
   adns_r_soa_raw=            6,
   adns_r_soa=                   adns_r_soa_raw|adns__qtf_mail822, 
-  adns_r_soa_mf=                adns_r_soa_raw|adns__qtf_masterfmt,
-  
-  adns_r_null=              10,
-  adns_r_null_mf=               adns_r_null|adns__qtf_masterfmt,
   
   adns_r_ptr_raw=           12,
   adns_r_ptr=                   adns_r_ptr_raw|adns__qtf_deref,
-  adns_r_ptr_mf=                adns_r_ptr_raw|adns__qtf_masterfmt,
   
   adns_r_hinfo=             13,  
-  adns_r_hinfo_mf=              adns_r_hinfo|adns__qtf_masterfmt,
   
   adns_r_mx_raw=            15,
   adns_r_mx=                    adns_r_mx_raw|adns__qtf_deref,
-  adns_r_mx_mf=                 adns_r_mx_raw|adns__qtf_masterfmt,
   
   adns_r_txt=               16,
-  adns_r_txt_mf=                adns_r_txt|adns__qtf_masterfmt,
   
   adns_r_rp_raw=            17,
   adns_r_rp=                    adns_r_rp_raw|adns__qtf_mail822,
-  adns_r_rp_mf=                 adns_r_rp_raw|adns__qtf_masterfmt
+
+  adns_r_addr=                  adns_r_a|adns__qtf_deref
   
 } adns_rrtype;
 
@@ -104,59 +99,95 @@ typedef enum {
  * not usually legal in domain names will be quoted as \X
  * (if the character is 33-126 except \ and ") or \DDD.
  *
- * _qtf_anyquote is ignored for _mf queries.
- *
  * Do not ask for _raw records containing mailboxes without
  * specifying _qf_anyquote.
  */
 
 typedef enum {
   adns_s_ok,
+
+  /* locally induced errors */
+  adns_s_nomemory,
+  adns_s_unknownrrtype,
+  
+  /* remotely induced errors, detected locally */
   adns_s_timeout,
-  adns_s_nolocalmem,
   adns_s_allservfail,
-  adns_s_servfail,
-  adns_s_notimplemented,
-  adns_s_refused,
-  adns_s_reasonunknown,
   adns_s_norecurse,
-  adns_s_serverfaulty,
-  adns_s_unknownreply,
-  adns_s_invaliddata,
+  adns_s_invalidresponse,
+  adns_s_unknownformat,
+  
+  /* remotely induced errors, reported by remote server to us */
+  adns_s_rcodeservfail,
+  adns_s_rcodeformaterror,
+  adns_s_rcodenotimplemented,
+  adns_s_rcoderefused,
+  adns_s_rcodeunknown,
+  
   adns_s_max_tempfail= 99,
-  adns_s_inconsistent, /* PTR gives domain whose A does not match */
-  adns_s_cname, /* CNAME found where data eg A expected (not if _qf_loosecname) */
-  /* fixme: implement _s_cname */
-  adns_s_max_remotemisconfig= 199,
+
+  /* remote configuration errors */
+  adns_s_inconsistent, /* PTR gives domain whose A does not exist and match */
+  adns_s_prohibitedcname, /* CNAME found where eg A expected (not if _qf_loosecname) */
+  adns_s_answerdomaininvalid,
+  adns_s_answerdomaintoolong,
+  adns_s_invaliddata,
+  
+  adns_s_max_misconfig= 199,
+
+  /* permanent problems with the query */
+  adns_s_querydomainwrong,
+  adns_s_querydomaininvalid,
+  adns_s_querydomaintoolong,
+  
+  adns_s_max_misquery= 299,
+
+  /* permanent errors */
   adns_s_nxdomain,
   adns_s_nodata,
-  adns_s_invaliddomain,
-  adns_s_domaintoolong,
+  
 } adns_status;
 
 typedef struct {
-  char *dm;
+  int len;
+  union {
+    struct sockaddr sa;
+    struct sockaddr_in inet;
+  } addr;
+} adns_rr_addr;
+
+typedef struct {
+  char *host;
   adns_status astatus;
   int naddrs; /* temp fail => -1, perm fail => 0, s_ok => >0 */
-  struct in_addr *addrs;
-} adns_rr_dmaddr;
+  adns_rr_addr *addrs;
+} adns_rr_hostaddr;
 
 typedef struct {
-  char *a, *b;
+  char *(array[2]);
 } adns_rr_strpair;
 
 typedef struct {
   int i;
-  adns_rr_dmaddr dmaddr;
-} adns_rr_intdmaddr;
+  adns_rr_hostaddr ha;
+} adns_rr_inthostaddr;
 
 typedef struct {
+  /* Used both for mx_raw, in which case i is the preference and str the domain,
+   * and for txt, in which case each entry has i for the `text' length,
+   * and str for the data (which will have had an extra nul appended
+   * so that if it was plain text it is now a null-terminated string).
+   */
   int i;
   char *str;
 } adns_rr_intstr;
 
 typedef struct {
-  char *ns0, *rp;
+  adns_rr_intstr array[2];
+} adns_rr_intstrpair;
+
+typedef struct {
+  char *mname, *rname;
   unsigned long serial, refresh, retry, expire, minimum;
 } adns_rr_soa;
 
@@ -168,14 +199,16 @@ typedef struct {
   union {
     void *untyped;
     unsigned char *bytes;
-    char *(*str);                  /* ns_raw, cname, ptr, ptr_raw, txt, <any>_mf */
-    struct in_addr *inaddr;        /* a */
-    adns_rr_dmaddr *dmaddr;        /* ns */
-    adns_rr_strpair *strpair;      /* hinfo, rp, rp_raw */
-    adns_rr_intdmaddr *intdmaddr;  /* mx */
-    adns_rr_intstr *intstr;        /* mx_raw */
-    adns_rr_soa *soa;              /* soa, soa_raw */
-    /* NULL is empty */
+    char *(*str);                     /* ns_raw, cname, ptr, ptr_raw */
+    adns_rr_intstr *(*manyistr);      /* txt (list of strings ends with i=-1, str=0) */
+    adns_rr_addr *addr;               /* addr */
+    struct in_addr *inaddr;           /* a */
+    adns_rr_hostaddr *hostaddr;       /* ns */
+    adns_rr_intstrpair *intstrpair;   /* hinfo */
+    adns_rr_strpair *strpair;         /* rp, rp_raw */
+    adns_rr_inthostaddr *inthostaddr; /* mx */
+    adns_rr_intstr *intstr;           /* mx_raw */
+    adns_rr_soa *soa;                 /* soa, soa_raw */
   } rrs;
 } adns_answer;
 
@@ -202,14 +235,17 @@ typedef struct {
  *  If no (appropriate) requests are outstanding adns_query and adns_wait return ESRCH;
  */
 
-int adns_init(adns_state *newstate_r, adns_initflags flags, FILE *diagfile/*0=>stderr*/);
+int adns_init(adns_state *newstate_r, adns_initflags flags,
+             FILE *diagfile /*0=>stderr*/);
+
+int adns_init_strcfg(adns_state *newstate_r, adns_initflags flags,
+                    FILE *diagfile /*0=>discard*/, const char *configtext);
 
 int adns_synchronous(adns_state ads,
                     const char *owner,
                     adns_rrtype type,
                     adns_queryflags flags,
                     adns_answer **answer_r);
-/* Will not return EINTR. */
 
 /* NB: if you set adns_if_noautosys then _submit and _check do not
  * make any system calls; you must use adns_callback (possibly after
@@ -232,11 +268,10 @@ int adns_wait(adns_state ads,
              adns_query *query_io,
              adns_answer **answer_r,
              void **context_r);
-/* Might return EINTR - if so, try again */
 
 void adns_cancel(adns_query query);
 
-int adns_finish(adns_state);
+void adns_finish(adns_state);
 /* You may call this even if you have queries outstanding;
  * they will be cancelled.
  */
@@ -310,7 +345,7 @@ adns_status adns_rr_info(adns_rrtype type,
  *
  * Usually this routine will succeed.  Possible errors include:
  *  adns_s_nomemory
- *  adns_s_notimplemented (RR type not known)
+ *  adns_s_rrtypeunknown
  *  adns_s_invaliddata (*datap contained garbage)
  * If an error occurs then no memory has been allocated,
  * and *rrtname_r, *fmtname_r, *len_r and *data_r are undefined.