You will probably find that GNU Make is required.
+IPv6 SUPPORT
+
+If you build adns on a system without a definition for AF_INET6 in
+<netinet/in.h>, you will (probably) still be able to do lookups for
+IPv6 addresses, etc. However, adns will do this by including the
+header file adns-in6fake.h, which contains definitions of various
+IPv6-related structures (those in RFC2133) which I have just made up.
+They may not be the same as those which a later version of your system
+actually includes, which means that the versions of adns built
+before and after IPv6 support on your platform might not be binary
+compatible - EVEN FOR PROGRAMS WHICH DO NOT DO IPv6 LOOKUPS !
+
+On platforms with a `sa_len' field this feature will not work
+properly.
+
+
SECURITY AND PERFORMANCE - AN IMPORTANT NOTE
adns is not a full-service resolver. It does no caching of responses
--- /dev/null
+/*
+ * adns-in6fake.h
+ * - adns declarations for IPv6 compatibility on systems without it
+ */
+/*
+ *
+ * This file is
+ * Copyright (C) 2000 Ian Jackson <ian@davenant.greenend.org.uk>
+ *
+ * It is part of adns, which is
+ * Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+ * Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * For the benefit of certain LGPL'd `omnibus' software which provides
+ * a uniform interface to various things including adns, I make the
+ * following additional licence. I do this because the GPL would
+ * otherwise force either the omnibus software to be GPL'd or for the
+ * adns-using part to be distributed separately.
+ *
+ * So, you may also redistribute and/or modify adns.h (but only the
+ * public header file adns.h and not any other part of adns) under the
+ * terms of the GNU Library General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * Note that adns itself is GPL'd. Authors of adns-using applications
+ * with GPL-incompatible licences, and people who distribute adns with
+ * applications where the whole distribution is not GPL'd, are still
+ * likely to be in violation of the GPL. Anyone who wants to do this
+ * should contact Ian Jackson. Please note that to avoid encouraging
+ * people to infringe the GPL as it applies the body of adns, I think
+ * that if you take advantage of the special exception to redistribute
+ * just adns.h under the LGPL, you should retain this paragraph in its
+ * place in the appropriate copyright statements.
+ *
+ *
+ * You should have received a copy of the GNU General Public License,
+ * or the GNU Library General Public License, as appropriate, along
+ * with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * $Id$
+ */
+
+#ifndef ADNS_IN6FAKE_H_INCLUDED
+#define ADNS_IN6FAKE_H_INCLUDED
+
+#define AF_INET6 10 /* copied from the Linux headers -iwj */
+
+struct in6_addr { unsigned char s6_addr[16]; };
+
+struct sockaddr_in6 {
+ /* Bezerkely invented a useless sa_len member whose effect is to
+ * pointlessly mess up the layout of this struct. The hackery below
+ * is to try to make sure that the struct sockaddr_in6 we make up
+ * here probably has the same location and size for sin6_family
+ * as both a struct sockaddr and as any putative future real
+ * struct sockadr_in6.
+ */
+ union {
+ struct sockaddr adns__in6fake_sa;
+ struct {
+ unsigned short adns__in6fake_sin6_family;
+ unsigned short adns__in6fake_sin6_port;
+ unsigned long adns__in6fake_sin6_flowinfo;
+ struct in6_addr adns__in6fake_sin6_addr;
+ } adns__in6fake_sin6;
+ } adns__in6fake_union;
+};
+
+#define sin6_family adns__in6fake_union.adns__in6fake_sa.sa_family
+#define sin6_port adns__in6fake_union.adns__in6fake_sin6.adns__in6fake_sin6_port;
+#define sin6_flowinfo adns__in6fake_union.adns__in6fake_sin6.adns__in6fake_sin6_addr;
+#define sin6_addr adns__in6fake_union.adns__in6fake_sin6.adns__in6fake_sin6_addr;
+
+#endif
#include <sys/time.h>
#include <unistd.h>
+#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;
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 {
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 */
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;
union {
struct sockaddr sa;
struct sockaddr_in inet;
+ struct sockaddr_in6 inet6;
} addr;
} adns_rr_addr;
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 */
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;
* 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
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,
DEEP_TYPE(mx_raw, "MX", "raw", intstr, pa_mx_raw, di_mx_raw, cs_inthost ),
DEEP_TYPE(txt, "TXT", 0, manyistr, pa_txt, 0, cs_txt ),
DEEP_TYPE(rp_raw, "RP", "raw", strpair, pa_rp, 0, cs_rp ),
+FLAT_TYPE(aaaa, "AAAA", 0, inaddr6, pa_inaddr6, di_inaddr6, cs_inaddr6 ),
+DEEP_TYPE(srv_raw,"SRV", "raw", srvraw, pa_srvraw, di_srvraw, cs_srvraw ),
FLAT_TYPE(addr, "A", "addr", addr, pa_addr, di_addr, cs_addr ),
DEEP_TYPE(ns, "NS", "+addr", hostaddr, pa_hostaddr,di_hostaddr,cs_hostaddr ),
DEEP_TYPE(ptr, "PTR","checked",str, pa_ptr, 0, cs_domain ),
DEEP_TYPE(mx, "MX", "+addr", inthostaddr,pa_mx, di_mx, cs_inthostaddr),
+DEEP_TYPE(srv, "SRV","+addr", srv, pa_srv, di_srv, cs_srv ),
DEEP_TYPE(soa, "SOA","822", soa, pa_soa, 0, cs_soa ),
DEEP_TYPE(rp, "RP", "822", strpair, pa_rp, 0, cs_rp ),