-/* $Id$ */
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2007-2009 by Daniel Stenberg
+/* Copyright 1998, 2009 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2007-2013 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* Define WIN32 when build target is Win32 API
*/
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#define WIN32
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+ !defined(WIN32) && !defined(__SYMBIAN32__)
+# define WIN32
#endif
#include <sys/types.h>
libc5-based Linux systems. Only include it on system that are known to
require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
- defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY)
+ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+ defined(ANDROID) || defined(__ANDROID__)
#include <sys/select.h>
#endif
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
#endif
#if defined(WATT32)
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <tcp.h>
+# include <netinet/in.h>
+# include <sys/socket.h>
+# include <tcp.h>
+#elif defined(_WIN32_WCE)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# include <winsock.h>
#elif defined(WIN32)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# include <winsock2.h>
# include <ws2tcpip.h>
#else
- #include <sys/socket.h>
- #include <netinet/in.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
+/*
+** c-ares external API function linkage decorations.
+*/
+
+#if !defined(CARES_STATICLIB) && \
+ (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+ /* __declspec function decoration for Win32 and Symbian DLL's */
+# if defined(CARES_BUILDING_LIBRARY)
+# define CARES_EXTERN __declspec(dllexport)
+# else
+# define CARES_EXTERN __declspec(dllimport)
+# endif
+#else
+ /* visibility function decoration for other cases */
+# if !defined(CARES_SYMBOL_HIDING) || \
+ defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
+# define CARES_EXTERN
+# else
+# define CARES_EXTERN CARES_SYMBOL_SCOPE_EXTERN
+# endif
+#endif
+
+
#define ARES_SUCCESS 0
/* Server error codes (ARES_ENODATA indicates no relevant answer) */
#define ARES_ENONAME 19
#define ARES_EBADHINTS 20
+/* Uninitialized library error code */
+#define ARES_ENOTINITIALIZED 21 /* introduced in 1.7.0 */
+
/* ares_library_init error codes */
-#define ARES_ELOADIPHLPAPI 21
-#define ARES_ELOADADVAPI32 22
-#define ARES_EADDRGetNetworkParams 23
+#define ARES_ELOADIPHLPAPI 22 /* introduced in 1.7.0 */
+#define ARES_EADDRGETNETWORKPARAMS 23 /* introduced in 1.7.0 */
+
+/* More error codes */
+#define ARES_ECANCELLED 24 /* introduced in 1.7.0 */
/* Flag values */
#define ARES_FLAG_USEVC (1 << 0)
#define ARES_FLAG_NOSEARCH (1 << 5)
#define ARES_FLAG_NOALIASES (1 << 6)
#define ARES_FLAG_NOCHECKRESP (1 << 7)
+#define ARES_FLAG_EDNS (1 << 8)
/* Option mask values */
#define ARES_OPT_FLAGS (1 << 0)
#define ARES_OPT_SOCK_RCVBUF (1 << 12)
#define ARES_OPT_TIMEOUTMS (1 << 13)
#define ARES_OPT_ROTATE (1 << 14)
+#define ARES_OPT_EDNSPSZ (1 << 15)
/* Nameinfo flag values */
#define ARES_NI_NOFQDN (1 << 0)
void *sock_state_cb_data;
struct apattern *sortlist;
int nsort;
+ int ednspsz;
};
struct hostent;
struct timeval;
struct sockaddr;
struct ares_channeldata;
+
typedef struct ares_channeldata *ares_channel;
-typedef void (*ares_callback)(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen);
-typedef void (*ares_host_callback)(void *arg, int status, int timeouts,
+
+typedef void (*ares_callback)(void *arg,
+ int status,
+ int timeouts,
+ unsigned char *abuf,
+ int alen);
+
+typedef void (*ares_host_callback)(void *arg,
+ int status,
+ int timeouts,
struct hostent *hostent);
-typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts,
- char *node, char *service);
+
+typedef void (*ares_nameinfo_callback)(void *arg,
+ int status,
+ int timeouts,
+ char *node,
+ char *service);
+
typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd,
- int type, void *data);
-
-int ares_library_init(int flags);
-void ares_library_cleanup(void);
-const char *ares_version(int *version);
-
-int ares_init(ares_channel *channelptr);
-int ares_init_options(ares_channel *channelptr, struct ares_options *options,
- int optmask);
-int ares_save_options(ares_channel channel, struct ares_options *options,
- int *optmask);
-void ares_destroy_options(struct ares_options *options);
-int ares_dup(ares_channel *dest, ares_channel src);
-void ares_destroy(ares_channel channel);
-void ares_cancel(ares_channel channel);
-void ares_set_socket_callback(ares_channel channel,
- ares_sock_create_callback callback,
- void *user_data);
-void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
- ares_callback callback, void *arg);
-void ares_query(ares_channel channel, const char *name, int dnsclass,
- int type, ares_callback callback, void *arg);
-void ares_search(ares_channel channel, const char *name, int dnsclass,
- int type, ares_callback callback, void *arg);
-void ares_gethostbyname(ares_channel channel, const char *name, int family,
- ares_host_callback callback, void *arg);
-int ares_gethostbyname_file(ares_channel channel, const char *name,
- int family, struct hostent **host);
-void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
- int family, ares_host_callback callback, void *arg);
-void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
- ares_socklen_t salen, int flags,
- ares_nameinfo_callback callback,
- void *arg);
-int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
-int ares_getsock(ares_channel channel, int *socks, int numsocks);
-struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
- struct timeval *tv);
-void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
-void ares_process_fd(ares_channel channel, ares_socket_t read_fd,
- ares_socket_t write_fd);
-
-int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
- int rd, unsigned char **buf, int *buflen);
-int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
- int alen, char **s, long *enclen);
-int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf,
- int alen, unsigned char **s, long *enclen);
+ int type,
+ void *data);
+
+CARES_EXTERN int ares_library_init(int flags);
+
+CARES_EXTERN void ares_library_cleanup(void);
+
+CARES_EXTERN const char *ares_version(int *version);
+
+CARES_EXTERN int ares_init(ares_channel *channelptr);
+
+CARES_EXTERN int ares_init_options(ares_channel *channelptr,
+ struct ares_options *options,
+ int optmask);
+
+CARES_EXTERN int ares_save_options(ares_channel channel,
+ struct ares_options *options,
+ int *optmask);
+
+CARES_EXTERN void ares_destroy_options(struct ares_options *options);
+
+CARES_EXTERN int ares_dup(ares_channel *dest,
+ ares_channel src);
+
+CARES_EXTERN void ares_destroy(ares_channel channel);
+
+CARES_EXTERN void ares_cancel(ares_channel channel);
+
+/* These next 3 configure local binding for the out-going socket
+ * connection. Use these to specify source IP and/or network device
+ * on multi-homed systems.
+ */
+CARES_EXTERN void ares_set_local_ip4(ares_channel channel, unsigned int local_ip);
+
+/* local_ip6 should be 16 bytes in length */
+CARES_EXTERN void ares_set_local_ip6(ares_channel channel,
+ const unsigned char* local_ip6);
+
+/* local_dev_name should be null terminated. */
+CARES_EXTERN void ares_set_local_dev(ares_channel channel,
+ const char* local_dev_name);
+
+CARES_EXTERN void ares_set_socket_callback(ares_channel channel,
+ ares_sock_create_callback callback,
+ void *user_data);
+
+CARES_EXTERN void ares_send(ares_channel channel,
+ const unsigned char *qbuf,
+ int qlen,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_query(ares_channel channel,
+ const char *name,
+ int dnsclass,
+ int type,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_search(ares_channel channel,
+ const char *name,
+ int dnsclass,
+ int type,
+ ares_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_gethostbyname(ares_channel channel,
+ const char *name,
+ int family,
+ ares_host_callback callback,
+ void *arg);
+
+CARES_EXTERN int ares_gethostbyname_file(ares_channel channel,
+ const char *name,
+ int family,
+ struct hostent **host);
+
+CARES_EXTERN void ares_gethostbyaddr(ares_channel channel,
+ const void *addr,
+ int addrlen,
+ int family,
+ ares_host_callback callback,
+ void *arg);
+
+CARES_EXTERN void ares_getnameinfo(ares_channel channel,
+ const struct sockaddr *sa,
+ ares_socklen_t salen,
+ int flags,
+ ares_nameinfo_callback callback,
+ void *arg);
+
+CARES_EXTERN int ares_fds(ares_channel channel,
+ fd_set *read_fds,
+ fd_set *write_fds);
+
+CARES_EXTERN int ares_getsock(ares_channel channel,
+ ares_socket_t *socks,
+ int numsocks);
+
+CARES_EXTERN struct timeval *ares_timeout(ares_channel channel,
+ struct timeval *maxtv,
+ struct timeval *tv);
+
+CARES_EXTERN void ares_process(ares_channel channel,
+ fd_set *read_fds,
+ fd_set *write_fds);
+
+CARES_EXTERN void ares_process_fd(ares_channel channel,
+ ares_socket_t read_fd,
+ ares_socket_t write_fd);
+
+CARES_EXTERN int ares_create_query(const char *name,
+ int dnsclass,
+ int type,
+ unsigned short id,
+ int rd,
+ unsigned char **buf,
+ int *buflen,
+ int max_udp_size);
+
+CARES_EXTERN int ares_mkquery(const char *name,
+ int dnsclass,
+ int type,
+ unsigned short id,
+ int rd,
+ unsigned char **buf,
+ int *buflen);
+
+CARES_EXTERN int ares_expand_name(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen,
+ char **s,
+ long *enclen);
+
+CARES_EXTERN int ares_expand_string(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen,
+ unsigned char **s,
+ long *enclen);
/*
- * NOTE: before c-ares 1.6.1 we would most often use the system in6_addr
+ * NOTE: before c-ares 1.7.0 we would most often use the system in6_addr
* struct below when ares itself was built, but many apps would use this
* private version since the header checked a HAVE_* define for it. Starting
- * with 1.6.1 we always declare and use our own to stop relying on the
+ * with 1.7.0 we always declare and use our own to stop relying on the
* system's one.
*/
struct ares_in6_addr {
} _S6_un;
};
-/*
- * TODO: the structs 'addrttl' and 'addr6ttl' really should get their names
- * prefixed with ares_ to keep them in our own "name space".
- */
-struct addrttl {
+struct ares_addrttl {
struct in_addr ipaddr;
int ttl;
};
-struct addr6ttl {
+
+struct ares_addr6ttl {
struct ares_in6_addr ip6addr;
int ttl;
};
+struct ares_srv_reply {
+ struct ares_srv_reply *next;
+ char *host;
+ unsigned short priority;
+ unsigned short weight;
+ unsigned short port;
+};
+
+struct ares_mx_reply {
+ struct ares_mx_reply *next;
+ char *host;
+ unsigned short priority;
+};
+
+struct ares_txt_reply {
+ struct ares_txt_reply *next;
+ unsigned char *txt;
+ size_t length; /* length excludes null termination */
+};
+
+struct ares_naptr_reply {
+ struct ares_naptr_reply *next;
+ unsigned char *flags;
+ unsigned char *service;
+ unsigned char *regexp;
+ char *replacement;
+ unsigned short order;
+ unsigned short preference;
+};
+
+struct ares_soa_reply {
+ char *nsname;
+ char *hostmaster;
+ unsigned int serial;
+ unsigned int refresh;
+ unsigned int retry;
+ unsigned int expire;
+ unsigned int minttl;
+};
+
/*
** Parse the buffer, starting at *abuf and of length alen bytes, previously
** obtained from an ares_search call. Put the results in *host, if nonnull.
** their TTLs in that array, and set *naddrttls to the number of addresses
** so written.
*/
-int ares_parse_a_reply(const unsigned char *abuf, int alen,
- struct hostent **host,
- struct addrttl *addrttls, int *naddrttls);
-int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
- struct hostent **host,
- struct addr6ttl *addrttls, int *naddrttls);
-int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
- int addrlen, int family, struct hostent **host);
-int ares_parse_ns_reply(const unsigned char *abuf, int alen,
- struct hostent **host);
-void ares_free_string(void *str);
-void ares_free_hostent(struct hostent *host);
-const char *ares_strerror(int code);
+
+CARES_EXTERN int ares_parse_a_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host,
+ struct ares_addrttl *addrttls,
+ int *naddrttls);
+
+CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host,
+ struct ares_addr6ttl *addrttls,
+ int *naddrttls);
+
+CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf,
+ int alen,
+ const void *addr,
+ int addrlen,
+ int family,
+ struct hostent **host);
+
+CARES_EXTERN int ares_parse_ns_reply(const unsigned char *abuf,
+ int alen,
+ struct hostent **host);
+
+CARES_EXTERN int ares_parse_srv_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_srv_reply** srv_out);
+
+CARES_EXTERN int ares_parse_mx_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_mx_reply** mx_out);
+
+CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_txt_reply** txt_out);
+
+CARES_EXTERN int ares_parse_naptr_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_naptr_reply** naptr_out);
+
+CARES_EXTERN int ares_parse_soa_reply(const unsigned char* abuf,
+ int alen,
+ struct ares_soa_reply** soa_out);
+
+CARES_EXTERN void ares_free_string(void *str);
+
+CARES_EXTERN void ares_free_hostent(struct hostent *host);
+
+CARES_EXTERN void ares_free_soa(struct ares_soa_reply *soa);
+
+CARES_EXTERN void ares_free_data(void *dataptr);
+
+CARES_EXTERN const char *ares_strerror(int code);
+
+/* TODO: Hold port here as well. */
+struct ares_addr_node {
+ struct ares_addr_node *next;
+ int family;
+ union {
+ struct in_addr addr4;
+ struct ares_in6_addr addr6;
+ } addr;
+};
+
+CARES_EXTERN int ares_set_servers(ares_channel channel,
+ struct ares_addr_node *servers);
+
+/* Incomming string format: host[:port][,host[:port]]... */
+CARES_EXTERN int ares_set_servers_csv(ares_channel channel,
+ const char* servers);
+
+CARES_EXTERN int ares_get_servers(ares_channel channel,
+ struct ares_addr_node **servers);
+
+CARES_EXTERN const char *ares_inet_ntop(int af, const void *src, char *dst,
+ ares_socklen_t size);
+
+CARES_EXTERN int ares_inet_pton(int af, const char *src, void *dst);
+
#ifdef __cplusplus
}