/* ==========================================================================
* lookup.h - Simple DNS Query Interface
* --------------------------------------------------------------------------
* Copyright (c) 2004, 2005, 2006 Barracuda Networks, Inc.
* Copyright (c) 2006 William Ahern <william@25thandClement.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
* --------------------------------------------------------------------------
* History
*
* 2006-04-23
* Completely refactored interface in preparation for adding
* cancellations.
*
* 2006-02-14 (william@25thandClement.com)
* Published by Barracuda Networks, originally authored by
* employee William Ahern (wahern@barracudanetworks.com).
* --------------------------------------------------------------------------
* Description
*
* Simple DNS query state machine which wraps the c-ares asynchronous client
* DNS library. Supports compound queries for one or more of the following
* record types: PTR, A, AAAA, CNAME, NS, MX, TXT, SOA and SRV.
*
* ==========================================================================
*/
#ifndef EVNET_LOOKUP_H
#define EVNET_LOOKUP_H
#include <sys/time.h> /* struct timeval */
#if !_WIN32
#include <sys/socket.h> /* struct sockaddr struct sockaddr_storage */
#include <netinet/in.h> /* struct sockaddr_in struct sockaddr_in6 */
#include <netdb.h> /* NI_MAXHOST */
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#ifndef NI_MAXHOST
#define NI_MAXHOST 1024
#endif
#define LOOKUP_SUCCESS(e) (!LOOKUP_FAILURE((e)))
#define LOOKUP_FAILURE(e) ((e) & LOOKUP_EBOUNDARY)
#define LOOKUP_WARNING(e) ((e) & LOOKUP_WBOUNDARY)
#define LOOKUP_MESSAGE(e) ((e) & LOOKUP_MBOUNDARY)
#define LOOKUP_E2WARNING(e) \
(LOOKUP_WBOUNDARY \
| ((e) \
& (~(LOOKUP_EBOUNDARY | LOOKUP_MBOUNDARY)) \
) \
)
#define LOOKUP_W2ERROR(e) \
(LOOKUP_EBOUNDARY \
| ((e) \
& (~(LOOKUP_WBOUNDARY | LOOKUP_MBOUNDARY)) \
) \
)
enum lookup_type {
LOOKUP_IN_PTR = 1 << 0,
LOOKUP_IN_A = 1 << 1,
LOOKUP_IN_AAAA = 1 << 2,
LOOKUP_IN_CNAME = 1 << 3,
LOOKUP_IN_NS = 1 << 4,
LOOKUP_IN_MX = 1 << 5,
LOOKUP_IN_TXT = 1 << 6,
LOOKUP_IN_SOA = 1 << 7,
LOOKUP_IN_SRV = 1 << 8,
};
enum lookup_section {
LOOKUP_SECTION_LOCAL = 0,
LOOKUP_SECTION_ANSWERS = 1 << 0,
LOOKUP_SECTION_AUTHORITY = 1 << 1,
LOOKUP_SECTION_ADDITIONAL = 1 << 2,
};
enum lookup_flag {
LOOKUP_PREFER_A = 1 << 0,
LOOKUP_PREFER_AAAA = 1 << 1,
LOOKUP_FALLBACK = 1 << 2,
};
enum lookup_errno {
LOOKUP_ESUCCESS = 0,
LOOKUP_EBOUNDARY = 0x0020, /* 32 - 63 */
LOOKUP_ESYSTEM,
LOOKUP_ETIMEDOUT,
LOOKUP_EARES,
LOOKUP_EBAD_FAMILY,
LOOKUP_EBAD_RESPONSE,
LOOKUP_EEMPTY_RESPONSE,
LOOKUP_EUNKNOWN_RESPONSE,
LOOKUP_EDUPLICATE_RESPONSE,
LOOKUP_ENOTFOUND,
LOOKUP_ENODATA,
LOOKUP_EBAD_REQUEST,
LOOKUP_WBOUNDARY = 0x0040, /* 64 - 127 */
LOOKUP_WSYSTEM,
LOOKUP_WTIMEDOUT,
LOOKUP_WARES,
LOOKUP_WBAD_RESPONSE,
LOOKUP_WEMPTY_RESPONSE,
LOOKUP_WUNKNOWN_RESPONSE,
LOOKUP_WDUPLICATE_RESPONSE,
LOOKUP_WNOTFOUND,
LOOKUP_WNODATA,
LOOKUP_WBAD_REQUEST,
LOOKUP_MBOUNDARY = 0x0100, /* 128 - 255 */
LOOKUP_NERR, /* Do not move, do not put anything below. */
};
extern const char *lookup_errlist[];
extern const unsigned lookup_nerr;
enum lookup_method {
LOOKUP_METHOD_BIND = 1,
LOOKUP_METHOD_FILE,
#if LOOKUP_CACHE_IMPLEMENTED
LOOKUP_METHOD_CACHE,
#endif
};
struct lookup_options {
char *resolv; /* Path to resolv file (/etc/resolv.conf). */
char *hosts; /* Path to hosts file (/etc/hosts). */
#if LOOKUP_CACHE_IMPLEMENTED
enum lookup_method order[3]; /* Lookup order, usually cache, file, bind. */
#else
enum lookup_method order[2]; /* Lookup order, usually file, bind. */
#endif
int loan_answers; /* If 0, then lookup_rr structures
* will be automatically freed upon
* return from the callback.
* Otherwise, lookup_rr_free() must
* be used to free the answers.
*/
#if LOOKUP_CACHE_IMPLEMENTED
unsigned cache_max; /* Maximum number of queries to cache. */
char *cache_map; /* Path to shared cache memory map. */
#endif
unsigned chain_max; /* Maximum length of CNAME chains
* tolerated.
*/
unsigned query_max; /* Maximum number of live queries to
* issue per lookup request (limit
* excessive work for compound
* queries).
*/
unsigned nchannels; /* Maximum number of C-Ares channels
* to employ. Currently ALL are
* instantiated up-front, rather
* than incrementally.
*/
};
extern const struct lookup_options lookup_defaults;
/*
* Query resource record.
*/
struct lookup_rr {
enum lookup_type type;
enum lookup_section section;
char qname[NI_MAXHOST];
size_t qnamelen;
unsigned ttl;
union {
struct {
unsigned short preference;
char host[NI_MAXHOST];
size_t hostlen;
} mx;
struct {
union {
struct sockaddr sa;
struct sockaddr_in sin;
#if USE_IPV6
struct sockaddr_in6 sin6;
#endif
struct sockaddr_storage ss;
} sa;
size_t salen;
} ip;
struct {
char host[NI_MAXHOST];
size_t hostlen;
char mbox[NI_MAXHOST];
size_t mboxlen;
unsigned int serial;
int refresh;
int retry;
int expire;
unsigned int minimum;
} soa;
struct {
char host[NI_MAXHOST];
size_t hostlen;
} ptr;
struct {
char host[NI_MAXHOST];
size_t hostlen;
} ns;
struct {
char data[NI_MAXHOST];
size_t datalen;
} txt;
struct {
char host[NI_MAXHOST];
size_t hostlen;
} cname;
struct {
unsigned short priority;
unsigned short weight;
unsigned short port;
char host[NI_MAXHOST];
size_t hostlen;
} srv;
} rr;
struct lookup_rr *next;
#ifdef LIBEVNET_SOURCE
int resolved;
int followed;
struct lookup_rr *alias;
unsigned long srvsum;
LIST_ENTRY(lookup_rr) le;
#endif
}; /* struct lookup_rr */
/*
* Synchronous-mode query result.
*/
struct lookup_result {
enum lookup_errno l_errno;
int nanswers;
struct lookup_rr *answers;
int nadditional;
struct lookup_rr *additional;
#ifdef LIBEVNET_SOURCE
struct lookup *lookup;
int done;
int sys_errno;
LIST_HEAD(,lookup_rr) l_answers;
LIST_HEAD(,lookup_rr) l_additional;
#endif
}; /* struct lookup_result */
/*
* Helper macro to create timeval structures on-the-fly (and on-the-stack),
* using compound literals from C99.
*/
#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)
#define lookup_tv(s) (&(struct timeval){ (s), 0 })
#endif
/*
* Declare some structures that might haven't been declared just yet.
*/
struct lookup;
struct arena_prototype;
struct event_base;
/*
* Open and close a lookup resource object.
*/
struct lookup *lookup_open(const struct lookup_options *, struct event_base *, const struct arena_prototype *);
void lookup_close(struct lookup *);
/*
* Core lookup routine.
*/
typedef void (*lookup_return)(int, struct lookup_rr *, int, struct lookup_rr *, enum lookup_errno, void *);
void lookup_result_free(struct lookup *, struct lookup_result *);
void lookup_rr_free(struct lookup *, struct lookup_rr *);
struct lookup_result *lookup_rr(struct lookup *, const char *, size_t, int, int, lookup_return, void *, struct timeval *);
struct lookup_result *lookup_ptr(struct lookup *, struct sockaddr *, socklen_t, int, lookup_return, void *, struct timeval *);
/*
* Error descriptions.
*/
enum lookup_errno lookup_errno(struct lookup *);
const char *lookup_strerror(struct lookup *);
/*
* Simplified, namesake interface.
*/
enum lookup_errno lookup_init(const struct lookup_options *, struct event_base *, const struct arena_prototype *);
enum lookup_errno lookup_reset(const struct lookup_options *, struct event_base *, const struct arena_prototype *);
struct lookup_result *lookup(const char *, size_t, int, int, lookup_return, void *, struct timeval *);
struct lookup_result *rlookup(struct sockaddr *, socklen_t, int, lookup_return, void *, struct timeval *);
#endif /* EVNET_LOOKUP_H */
syntax highlighted by Code2HTML, v. 0.9.1