X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/adns/blobdiff_plain/7c4090270e6de67aee4a27b20c184826299bd1bf..0d417fc2dcbc0609e46e5a88c301a40e35ded82a:/src/adns.h?ds=inline diff --git a/src/adns.h b/src/adns.h index 343501d..fd27c93 100644 --- a/src/adns.h +++ b/src/adns.h @@ -68,6 +68,10 @@ extern "C" { /* I really dislike this - iwj. */ #include #include +#ifndef AF_INET6 +#include "adns-in6fake.h" +#endif + /* All struct in_addr anywhere in adns are in NETWORK byte order. */ typedef struct adns__state *adns_state; @@ -84,6 +88,7 @@ typedef enum { adns_if_nosigpipe= 0x0040, /* applic has SIGPIPE set to SIG_IGN, do not protect */ adns_if_checkc_entex= 0x0100, /* do consistency checks on entry/exit to adns funcs */ adns_if_checkc_freq= 0x0300 /* do consistency checks very frequently (slow!) */ + adns_if_ip6= 0x1000 /* make default be adns_qf_ip6 */ } adns_initflags; typedef enum { @@ -96,9 +101,44 @@ typedef enum { 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_ip6= 0x00001000, /* return addrs as AF_INET6 in all cases */ + adns_qf_ip6mixed= 0x00002000, /* return mixture of AF_INET4 and AF_INET6 */ + adns_qf_ip4= 0x00003000, /* never return AF_INET6, even with _if_ip6 */ adns__qf_internalmask= 0x0ff00000 } adns_queryflags; +/* IPv6 support: + * adns_if_ip6 has the effect of changing the default from + * adns_qf_ip4 to adns_qf_ip6. + * + * query type _qf__ip4 _qf_ip6mixed _qf_ip6 + * + * _r_addr A? => AF_INET AAAA? => AF_INET6 AAAA? => AF_INET6 + * else fail else A? => AF_INET else A? => AF_INET6 + * + * _r_a A => AF_INET A => AF_INET A => AF_INET6 + * + * _r_aaaa AAAA => AF_INET6 AAAA => AF_INET6 AAAA => AF_INET6 + * + * Ie, + * _ip4: only A lookups will be done, and everything is + * returned as AF_INET addresses; + * _ip6mixed: will look for AAAA records first, and if there + * are any, return them as AF_INET6, otherwise like _ip4. + * _ip6: like _ip6mixed, but will return even IPv4 addresses in + * IPv6-mapped form inside AF_INET6, for all query types. + * + * Furthermore, there are configuration options which can prevent the + * use of either AAAA or A records for _r_addr; so it is safe to use + * _qf_ip6 and _r_addr without checking explicitly whether the host + * has IPv6 connectivity. + * + * Applications which do not support IPv4 should set none of these + * flags. Applications which have been `naively' converted to use + * AF_INET6 throughout should set adns_if_ip6. Applications which + * know what they are doing should know which flags to set :-). + */ + typedef enum { adns__rrt_typemask= 0x0ffff, adns__qtf_deref= 0x10000, /* dereference domains and perhaps produce extra data */ @@ -129,6 +169,11 @@ typedef enum { adns_r_rp_raw= 17, adns_r_rp= adns_r_rp_raw|adns__qtf_mail822, + adns_r_aaaa= 28, + + adns_r_srv_raw= 33, + adns_r_srv= adns_r_srv_raw|adns__qtf_deref, + adns_r_addr= adns_r_a|adns__qtf_deref } adns_rrtype; @@ -251,6 +296,7 @@ typedef struct { union { struct sockaddr sa; struct sockaddr_in inet; + struct sockaddr_in6 inet6; } addr; } adns_rr_addr; @@ -289,6 +335,20 @@ typedef struct { unsigned long serial, refresh, retry, expire, minimum; } adns_rr_soa; +typedef struct { + unsigned short priority; + unsigned short weight; + unsigned short port; + adns_rr_hostaddr ha; +} adns_rr_srv; + +typedef struct { + unsigned short priority; + unsigned short weight; + unsigned short port; + char *target; +} adns_rr_srvraw; + typedef struct { adns_status status; char *cname; /* always NULL if query was for CNAME records */ @@ -303,12 +363,15 @@ typedef struct { adns_rr_intstr *(*manyistr); /* txt (list of strings ends with i=-1, str=0) */ adns_rr_addr *addr; /* addr */ struct in_addr *inaddr; /* a */ + struct in6_addr *inaddr6; /* aaaa */ 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 */ + adns_rr_srv *srv; /* srv */ + adns_rr_srvraw *srvraw; /* srv_raw */ } rrs; } adns_answer; @@ -424,6 +487,13 @@ int adns_init_strcfg(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. + * + * in6only + * in4only + * Return only IPv6, respectively only IPv4 addresses, in + * _rr_addr's. This may result in an adns_s_nodata error, if the + * application only supports, or the remote host only has, the wrong + * kind of address. * * There are a number of environment variables which can modify the * behaviour of adns. They take effect only if adns_init is used, and @@ -508,7 +578,32 @@ int adns_submit_reverse(adns_state ads, void *context, adns_query *query_r); /* type must be _r_ptr or _r_ptr_raw. _qf_search is ignored. - * addr->sa_family must be AF_INET or you get ENOSYS. + * addr->sa_family must be AF_INET or AF_INET6 you get ENOSYS. + */ + +int adns_getaddrinfo(adns_state ads, + const char *name, /* Eg, "www.example.coom" */ + const char *service, /* Eg, "http" */ + const char *protocol, /* Eg, "tcp" */ + unsigned short defaultport, /* Eg, 80 */ + adns_queryflags flags, + adns_answer **answer_r, int *invented_r); +/* Does an SRV lookup (RFC2052). If this fails, tries an AAAA or A + * lookup instead, and if found uses getservbyname to find the port + * number (or failing that, uses defaultport). In the `fallback' + * case, will invent an SRV record with have priority and weight == 0 + * and set *invented_r to 1; if real SRV records were found, will set + * *invented_r to 0. invented_r may be null but answer_r may not be. + * If _getaddrinfo returns nonzero, *answer_r and/or *invented_r may + * or may not have been overwritten and should not be used. + * + * NB, like adns_synchronous, can fail either by returning an errno + * value, or by returning an adns_answer with ->nrrs==0 and + * ->status!=0. + * + * You have to write two loops when using the returned value, an outer + * one to loop over the returned SRV's, and an inner one to loop over + * the addresses for each one. */ int adns_submit_reverse_any(adns_state ads,