/*
* adns.h
- * - adns user-visible API (single-threaded, without any locking)
+ * - adns user-visible API
*/
/*
*
* This file is
- * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+ * Copyright (C) 1997-2000,2003,2006 Ian Jackson
*
* It is part of adns, which is
- * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
- * Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
- *
+ * Copyright (C) 1997-2000,2003,2006 Ian Jackson
+ * Copyright (C) 1999-2000,2003,2006 Tony Finch
+ * Copyright (C) 1991 Massachusetts Institute of Technology
+ *
* 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)
#include <netinet/in.h>
#include <sys/time.h>
#include <unistd.h>
+#include <net/if.h>
#ifdef __cplusplus
extern "C" { /* I really dislike this - iwj. */
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_addrlit_scope_forbid=0x00002000,/* forbid %<scope> in IPv6 literals */
+ adns_qf_addrlit_scope_numeric=0x00004000,/* %<scope> may only be numeric */
+ adns_qf_addrlit_ipv4_quadonly=0x00008000,/* reject non-dotted-quad ipv4 */
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__qtf_bigaddr=0x1000000,/* use the new larger sockaddr union */
+
+ adns__qtf_deref= adns__qtf_deref_bit|adns__qtf_bigaddr
+ ,/* dereference domains; perhaps get extra data */
+
adns_r_unknown= 0x40000,
/* To use this, ask for records of type <rr-type-code>|adns_r_unknown.
* adns will not process the RDATA - you'll get adns_rr_byteblocks,
} 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;
+} adns_sockaddr;
+
typedef struct {
int len;
- union {
- struct sockaddr sa;
- struct sockaddr_in inet;
- } addr;
+ adns_sockaddr addr;
} adns_rr_addr;
+typedef struct {
+ /* the old v4-only structure; handy if you have complicated binary
+ * compatibility problems. */
+ int len;
+ adns_sockaddr_v4only addr;
+} adns_rr_addr_v4only;
+
typedef struct {
char *host;
adns_status astatus;
* requested.
*/
+/* Threads:
+ * adns does not use any static modifiable state, so it
+ * is safe to call adns_init several times and then use the
+ * resulting adns_states concurrently.
+ * However, it is NOT safe to make simultaneous calls into
+ * adns using the same adns_state; a single adns_state must be used
+ * only by one thread at a time. You can solve this problem by
+ * having one adns_state per thread, or if that isn't feasible, you
+ * could maintain a pool of adns_states. Unfortunately neither of
+ * these approaches has optimal performance.
+ */
+
int adns_init(adns_state *newstate_r, adns_initflags flags,
FILE *diagfile /*0=>stderr*/);
* 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_r,
+ socklen_t *salen_io /* updated iff OK or ENOSPC */);
+int adns_addr2text(const struct sockaddr *sa, adns_queryflags flags,
+ char *buffer, int *buflen_io /* updated ONLY on 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_io < ADNS_ADDR2TEXT_BUFLEN or
+ * *salen_io < sizeof(adns_sockaddr). On return,
+ * *buflen_io or *salen_io 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);